Golang语言社区go学习代码世界

go语言传递struct, pointer和interface的

2017-09-07  本文已影响189人  CodingCode

go语言函数传参可以传递struct,传递pointer,还有传递interface,他们主要区别是什么呢?

package main

import (
    "fmt"
    "unsafe"
    "reflect"
)

type MyInterface interface {
}

type MyStruct struct {
   i1 int64
   i2 int64
   i3 int64
   i4 int64
   i5 int64
}

func Hello1(p MyStruct) {
   fmt.Println("size:", unsafe.Sizeof(p), "; type:", reflect.TypeOf(p), "; value:", reflect.ValueOf(p))
}

func Hello2(p * MyStruct) {
   fmt.Println("size:", unsafe.Sizeof(p), "; type:", reflect.TypeOf(p), "; value:", reflect.ValueOf(p))
}

func Hello3(p MyInterface) {
   fmt.Println("size:", unsafe.Sizeof(p), "; type:", reflect.TypeOf(p), "; value:", reflect.ValueOf(p))
}

//func Hello4(p * MyInterface) {
//   fmt.Println("size:", unsafe.Sizeof(p), "; type:", reflect.TypeOf(p), "; value:", reflect.ValueOf(p))
//}

func main() {
   m := MyStruct { 11,22,33,44,55 }
   Hello1(m)
   Hello2(&m)
   Hello3(m)
   //Hello4((* MyInterface)(&m))
}

运行结果如下

$ go build main.go && ./main 
size: 40 ; type: main.MyStruct ; value: {11 22 33 44 55}
size: 8 ; type: *main.MyStruct ; value: &{11 22 33 44 55}
size: 16 ; type: main.MyStruct ; value: {11 22 33 44 55}

可以看到三个的区别

  1. 传struct是传值,把原数据做完整拷贝,作为参数传递给callee
  2. 传pointer,传递的是原数据的一个指针,从而在callee里面如果对原数据做了改动,会反映到caller
  3. 传interface,传递的是一个interface对象,这个对象占用16字节长度,包含一个指向原数据的指针,和一个指向运行时类型信息的指针。

当然对于指向interface的指针这种用法是几乎没有用到的(例子中的Hello4()函数,编译没有成功,我不知道应该怎么写),也不建议这么用,因为interface本身差不多就是一个指针(其实是两个指针),stackoverflow有一个问答介绍这个问题: https://stackoverflow.com/questions/44370277/type-is-pointer-to-interface-not-interface-confusion
简单的说就是不要有interface指针这种用法。

下面一篇文章来介绍函数如何传递interface.

上一篇下一篇

猜你喜欢

热点阅读