Go中的某些类型是引用类型:地图,切片,通道,函数和方法。
有时您需要使用指向引用的指针。例如,
type Stack []interface{}
func (stack *Stack) Push(x interface{}) {
*stack = append(*stack, x)
}
您需要它,因为所有参数都是通过复制值传递的,而append()
可能需要重新分配切片中的内存容量不够大。我知道了。
第一个问题。 map
类型怎么样?如果我有基于map
的自定义类型,如果需要某些键:值插入或删除,我是否应该总是传递一个指向它的指针?
第二个问题。其他参考类型怎么样?例如Channel
。我可以想象一种情况,我根据一个通道构建一个自定义类型,为传递给通道的值实现一些自定义预处理。指针也需要在这里?
很抱歉,如果这是基本的,但我真的想要很好地掌握这个主题。
答案 0 :(得分:5)
当您将所有内容视为值时,规则相当容易,其中某些值在内部包含指针。
当然有例外情况,例如,如果您希望能够完全换出地图,则需要使用指针来执行此操作,但这些情况很少见。
答案 1 :(得分:1)
“价值类型”和“参考类型”之间并没有真正的二分法。 “引用类型”仅用于描述一个值类型,其“值”完全由单个指针组成。
这适用于地图和通道类型,它们基本上是指向内部结构的指针类型。但是对于切片来说这并不完全正确,因为切片是复合类型(基本上是结构),由两个整数值(长度和容量)和一个指针(指向元素)组成。所以它是一个关于元素的“引用类型”,它们通过指针访问,但它是一个关于长度和容量的“值类型”。
附加到切片上的操作取决于其长度和可能的容量,因此需要更改切片的“值”,而分配到适当位置的元素只使用指针,因此不需要更改“值”切片。如果您希望将指针更改为指向与另一个切片相同的指针(您可以通过指定切片执行此操作),则可能还需要更改切片的“值”。
“参考类型”,地图和频道类似。更改地图或通道的“内容”(指针指向的内容)不需要更改地图或通道的“值”。但是,如果您想将指针更改为指向不同的基础地图或通道,则可以更改地图或通道变量的“值”。