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号