go语言传递struct, pointer和interface的差异

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.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,774评论 0 9
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,211评论 30 472
  • 原文地址:C语言函数调用栈(一)C语言函数调用栈(二) 0 引言 程序的执行过程可看作连续的函数调用。当一个函数执...
    小猪啊呜阅读 4,678评论 1 19
  • 307、setValue:forKey和setObject:forKey的区别是什么? 答:1, setObjec...
    AlanGe阅读 1,586评论 0 1
  • 多线程、特别是NSOperation 和 GCD 的内部原理。运行时机制的原理和运用场景。SDWebImage的原...
    LZM轮回阅读 2,039评论 0 12