go語(yǔ)言函數(shù)傳參可以傳遞struct,傳遞pointer瑰排,還有傳遞interface殿托,他們主要區(qū)別是什么呢?
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))
}
運(yùn)行結(jié)果如下
$ 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}
可以看到三個(gè)的區(qū)別
- 傳struct是傳值短蜕,把原數(shù)據(jù)做完整拷貝氢架,作為參數(shù)傳遞給callee
- 傳pointer,傳遞的是原數(shù)據(jù)的一個(gè)指針朋魔,從而在callee里面如果對(duì)原數(shù)據(jù)做了改動(dòng)岖研,會(huì)反映到caller
- 傳interface,傳遞的是一個(gè)interface對(duì)象警检,這個(gè)對(duì)象占用16字節(jié)長(zhǎng)度孙援,包含一個(gè)指向原數(shù)據(jù)的指針,和一個(gè)指向運(yùn)行時(shí)類型信息的指針扇雕。
當(dāng)然對(duì)于指向interface的指針這種用法是幾乎沒(méi)有用到的(例子中的Hello4()函數(shù)拓售,編譯沒(méi)有成功,我不知道應(yīng)該怎么寫)镶奉,也不建議這么用础淤,因?yàn)閕nterface本身差不多就是一個(gè)指針(其實(shí)是兩個(gè)指針),stackoverflow有一個(gè)問(wèn)答介紹這個(gè)問(wèn)題: https://stackoverflow.com/questions/44370277/type-is-pointer-to-interface-not-interface-confusion
簡(jiǎn)單的說(shuō)就是不要有interface指針這種用法哨苛。
下面一篇文章來(lái)介紹函數(shù)如何傳遞interface.