前往:将引用类型作为参数

oop*_*ode 2 parameters reference go

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

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

type Stack []interface{}
func (stack *Stack) Push(x interface{}) { 
    *stack = append(*stack, x)
}
Run Code Online (Sandbox Code Playgroud)

之所以需要它,是因为所有参数都是通过复制值来传递的,并且append()可能需要在分片的容量不够大的情况下重新分配内存。我明白了。

第一个问题。怎么样map的类型?如果我有一个基于的自定义类型map,如果预期会发生一些key:value插入或删除操作,我是否最好始终传递一个指向它的指针?

第二个问题。那其他参考类型呢?Channel, 例如。我可以想象这样一种情况,我将基于通道构建自定义类型,以对传递到通道的值实施一些自定义预处理。这里也需要指针吗?

抱歉,这是基本知识,但是我真的想很好地理解这个主题。

Jim*_*imB 5

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

  • slices(切片):当您可能需要修改长度或容量(这会更改切片的值)时,请使用指针。
  • maps:不要使用指针,因为map的值不会随着修改而改变。
  • 函数和方法:不要使用指针,通过函数值可以达到相同的效果。
  • chan:不要使用指针。

当然也有例外,例如,如果您希望能够完全交换出地图,则需要使用指针进行交换,但这是极少数情况。


new*_*cct 5

“值类型”和“引用类型”之间并不存在真正的二分法。“引用类型”仅用于描述其“值”完全由单个指针组成的值类型。

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

追加到切片会对其长度和潜在容量进行操作,因此需要更改切片的“值”,而就地分配元素仅使用指针,因此不需要更改切片的“值” 。如果您希望将指针更改为指向与另一个切片相同的指针(您可以通过分配给切片来完成),您可能还需要更改切片的“值”。

“参考类型”、地图和频道也类似。更改地图或通道的“内容”(位于指针指向的内容中)不需要更改地图或通道的“值”。但是,如果您想更改指针以指向不同的底层映射或通道,那么您将更改映射或通道变量的“值”。