今天来讲go 语言中的 struct——结构体,让我费解的表达
1.struct指针类型居然能直接通过点符操作获取指向的结构体中成员的值
先来看段代码吧:
package main
import "fmt"
type tree struct {
h int
w int
name string
}
func main() {
t:=tree{1,2,"tree1"}//创建一个结构体tree类型的变量
var ptr *tree = &t
fmt.Println(ptr.name)//output:tree1 ptr.name等价于(*ptr).name
}
WTF!?这是什么操作?表示看不懂啊
其实不光光是结构体有这种操作,数组也有,但是引用底层数组的slice类型就不行了
package main
import "fmt"
func main() {
ptr:=[4]int{1,2,3}
p:=&ptr
fmt.Println((*p)[0]);fmt.Println(p[0])//效果相同
slice:=[]int{1,2,3}
p1:=&slice
fmt.Println((*p1)[0])//不能写成p1[0]
fmt.Println(cap(slice))//output:3
}
原因:Go语言自动将ptr.name,p[0]这样的表达自动解引用
2.函数返回值必须是指针才能对struct内的成员的值进行更新
可能表达不准确,先上代码
package main
type man struct {
name string
age 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 main
import "fmt"
type man struct {
name string
age int
}
func getManByName(name string) man {
return man{name:name}
}
func main() {
m:=getManByName("hello")
m.age = 30
fmt.Println(m)//output:{hello 30}
}
既然是一个值,那么可以将值赋值给变量,就可以进行相关操作了。当然还有另外一种写法:
package main
type man struct {
name string
age int
}
func getManByName(name string) *man {
return &man{name:name}
}
func main() {
getManByName("hello").age = 30
}
返回一个类型为指针的值就不会出现编译出错的情况了,这里返回的是一个地址,Go语言自动解引用,修改在函数内创建的struct