You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
obsidian-sync/日常学习/golang/引用(指针)传递和值传递.md

2.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

golang 中默认是值传递和java有所区别需要注意。 在 C 语言中,数组变量是指向第一个元素的指针,但是 Go 语言中并不是。Go 语言中,数组变量属于值类型(value type),因此当一个数组变量被赋值或者传递时,实际上会复制整个数组。 为了避免复制数组,一般会传递指向数组的指针。例如:

func square(arr *[3]int) {  
	for i, num := range *arr {  
		(*arr)[i] = num * num  
	}  
}  
  
func TestArrayPointer(t *testing.T) {  
	a := [...]int{1, 2, 3}  
	square(&a)  
	fmt.Println(a) // [1 4 9]  
	if a[1] != 4 && a[2] != 9 {  
		t.Fatal("failed")  
	}  
}

值接收者与指针接收者

某个类型定义的方法其接收者既有值类型又有指针类型。例如自定义heap实现

type IntHeap []int  
  
// Push IntHeap全局共享切只有一个所以需要对类型本身进行操作所以使用指针  
func (h *IntHeap) Push(x any) {  
    //append需要传入切片切片是引用传递所以需要*h,  
    *h = append(*h, x.(int))  
}  
  
// Pop  
//  
//  @Description: 从数组移除一个元素  
//  @receiver h  
//  @return any  
func (h *IntHeap) Pop() any {  
    old := *h  
    n := len(old)  
    x := old[n-1]  
    *h = old[0 : n-1]  
    return x  
}  
  
// Len  
//  
//  @Description: 计算元素大小  
//  @receiver h  
//  @return int  
func (h IntHeap) Len() int {  
    return len(h)  
}  
  
// Less  
//  
//  @Description: 比较大小  
//  @receiver h  
//  @param i  
//  @param j  
//  @return bool  
func (h IntHeap) Less(i, j int) bool {  
    return h[i] < h[j]  
}  
  
// Swap  
//  
//  @Description: 交换i,j下标元素  
//  @receiver h  
//  @param i  
//  @param j  
func (h IntHeap) Swap(i, j int) {  
    h[i], h[j] = h[j], h[i]  
}

其中Push和Pop方法是指针接收其他方法是值接收。其中Push和Pop方法需要设置对象本身例如代码中的数组因此必须使用指针避免复制。Swap方法较为特殊golang默认会交换指针。