go 的形参
注意
记录一个 go 语言编程中,可能不小心忽略的一个点,
-
当函数的
出参如果是 数组、结构体、 类型时,是不需要声明的,可以直接使用。 -
但是如果
出参是指针类型(结构体指针或者map类型),则必须要显示的声明。
代码示例
type person struct {
name string
}
func main() {
r := getList()
fmt.Println(r)
m := getMap()
fmt.Println(m)
p := getPerson()
fmt.Println(p)
// 会报错
pp := getPointer()
fmt.Println(pp)
}
func getList() (l []int) {
for i := 0; i < 10; i++ {
l = append(l, i)
}
return l
}
func getMap() (m map[int]int) {
for i := 0; i < 5; i++ {
m[i] = i
}
return m
}
func getPerson() (p person) {
p.name = "张三"
return p
}
func getPointer() (p *person) {
p.name = "张三"
return p
}
为什么指针需要声明呢?
- 返回值是结构体时,编译器自动初始化一个空结构体;
- 返回值是指针时,编译器只初始化一个 nil 指针,需要你手动 new() 或 &{}。
为什么返回切片不需要声明呢?
例如:
func add() (a []int) {
a = append(a, 100)
return a
}
这是因为,go的底层逻辑
当 a 是 nil(或容量不够)时,append 自动调用了 make() 分配新底层数组;然后返回新的 slice;再赋值给 a。
go的底层进行了如下判断(伪代码)
if cap(a) == 0 {
newSlice := make([]int, len(a)+1)
copy(newSlice, a)
newSlice[len(a)] = 100
return newSlice
}
所有上面代码的逻辑等价于
func add() (a []int) {
a = make([]int, 0) // append 自动帮你做了这件事
a = append(a, 100)
return a
}
浙公网安备 33010602011771号