Go语言,struct结构体的那些奇怪的用法

来源:互联网 发布:摩尔定律失效 知乎 编辑:程序博客网 时间:2024/05/18 02:54

博主作为一个从JAVA入门的小伙子,表示Go语言中的某些表达真的太奇怪了,于是准备写几篇博客记录下,java程序员眼中Go语言中的那些理解起来心力交瘁的用法

今天来讲struct——结构体,让我费解的表达

1.struct指针类型居然能直接通过点符操作获取指向的结构体中成员的值

先来看段代码吧:

package mainimport "fmt"type tree struct {h intw intname string}func main() {t:=tree{1,2,"tree1"}//创建一个结构体tree类型的变量var ptr *tree = &tfmt.Println(ptr.name)//output:tree1 ptr.name等价于(*ptr).name}
WTF!?这是什么操作?表示看不懂啊

其实不光光是结构体有这种操作,数组也有,但是引用底层数组的slice类型就不行了

package mainimport "fmt"func main() {ptr:=[4]int{1,2,3}p:=&ptrfmt.Println((*p)[0]);fmt.Println(p[0])//效果相同slice:=[]int{1,2,3}p1:=&slicefmt.Println((*p1)[0])//不能写成p1[0]fmt.Println(cap(slice))//output:3}
原因:Go语言自动将ptr.name,p[0]这样的表达自动解引用

2.函数返回值必须是指针才能对struct内的成员的值进行更新

可能表达不准确,先上代码

package maintype man struct {name stringage int}func getManByName(name string) man {return man{name:name}}func main() {getManByName("hello").age = 30}
如果说你是一个java程序员,而且如果你把struct类型当作java中的类,你会觉得:诶,没毛病啊?哪里不对么?

醒醒!这不是java中的匿名对象!

当你编译时,Go就会报错:cannot assign to getManByName("hello").age 翻译:不能指定getManByName("hello").age
Go语言中,调用函数返回的是值而不是一个可取地址的变量,而java中的返回值是一个指向变量的匿名变量,机制完全不同。接下来修改这段代码:

package mainimport "fmt"type man struct {name stringage int}func getManByName(name string) man {return man{name:name}}func main() {m:=getManByName("hello")m.age = 30fmt.Println(m)//output:{hello 30}}
既然是一个值,那么可以将值赋值给变量,就可以进行相关操作了。当然还有另外一种写法:

package maintype man struct {name stringage int}func getManByName(name string) *man {return &man{name:name}}func main() {getManByName("hello").age = 30}
返回一个类型为指针的值就不会出现编译出错的情况了,这里返回的是一个地址,Go语言自动解引用,修改在函数内创建的struct