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

今天来讲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









你可能感兴趣的:(Go,golang,Go语言)