Go:引用类型作为参数

时间:2015-07-01 19:47:20

标签: parameters go reference

Go中的某些类型是引用类型:地图,切片,通道,函数和方法。

有时您需要使用指向引用的指针。例如,

type Stack []interface{}
func (stack *Stack) Push(x interface{}) { 
    *stack = append(*stack, x)
}

您需要它,因为所有参数都是通过复制值传递的,而append()可能需要重新分配切片中的内存容量不够大。我知道了。

第一个问题。 map类型怎么样?如果我有基于map的自定义类型,如果需要某些键:值插入或删除,我是否应该总是传递一个指向它的指针?

第二个问题。其他参考类型怎么样?例如Channel。我可以想象一种情况,我根据一个通道构建一个自定义类型,为传递给通道的值实现一些自定义预处理。指针也需要在这里?

很抱歉,如果这是基本的,但我真的想要很好地掌握这个主题。

2 个答案:

答案 0 :(得分:5)

当您将所有内容视为值时,规则相当容易,其中某些值在内部包含指针。

  • 切片:当您需要修改长度或容量时使用指针,这会更改切片的值。
  • 地图:不要使用指针,因为地图值不会因修改而改变。
  • 函数和方法:不使用指针,通过函数值产生相同的效果。
  • :不要使用指针。

当然有例外情况,例如,如果您希望能够完全换出地图,则需要使用指针来执行此操作,但这些情况很少见。

答案 1 :(得分:1)

“价值类型”和“参考类型”之间并没有真正的二分法。 “引用类型”仅用于描述一个值类型,其“值”完全由单个指针组成。

这适用于地图和通道类型,它们基本上是指向内部结构的指针类型。但是对于切片来说这并不完全正确,因为切片是复合类型(基本上是结构),由两个整数值(长度和容量)和一个指针(指向元素)组成。所以它是一个关于元素的“引用类型”,它们通过指针访问,但它是一个关于长度和容量的“值类型”。

附加到切片上的操作取决于其长度和可能的容量,因此需要更改切片的“值”,而分配到适当位置的元素只使用指针,因此不需要更改“值”切片。如果您希望将指针更改为指向与另一个切片相同的指针(您可以通过指定切片执行此操作),则可能还需要更改切片的“值”。

“参考类型”,地图和频道类似。更改地图或通道的“内容”(指针指向的内容)不需要更改地图或通道的“值”。但是,如果您想将指针更改为指向不同的基础地图或通道,则可以更改地图或通道变量的“值”。