【发布时间】:2015-07-02 22:14:30
【问题描述】:
Go 中的某些类型是引用类型:映射、切片、通道、函数和方法。
有时您需要使用指向引用的指针。例如,
type Stack []interface{}
func (stack *Stack) Push(x interface{}) {
*stack = append(*stack, x)
}
您需要它,因为所有参数都是通过复制值来传递的,而append() 可能需要在切片容量不够大的情况下重新分配内存。我明白了。
第一个问题。map 类型怎么样?如果我有一个基于 map 的自定义类型,如果需要一些键值插入或删除,我是否应该始终传递一个指向它的指针?
第二个问题。其他引用类型呢?例如Channel。我可以想象这样一种情况,我基于通道构建自定义类型,以对传递给通道的值实现一些自定义预处理。这里也需要指针吗?
对不起,如果这是基本的,但我真的想很好地掌握这个主题。
【问题讨论】:
-
您将切片描述符与底层数组混淆了。 Go 中没有引用类型。你有价值观,你有指针。指针是“参考”。而且我不知道您的代码示例在做什么,但这当然不是必需的。值得一读blog.golang.org/go-slices-usage-and-internals
-
@evanmcdonnal:不,这需要一个指针,因为附加可能会分配一个新数组,从而更改内部数据指针以及 len 和 cap 值。 play.golang.org/p/Cm8AQXpK5J
-
@JimB 是的,我在操场上修补它时注意到了这一点。这种必要性是由愚蠢的设计引起的。只需使用接收器和返回类型
Stack定义方法并执行myStack = myStack.Push(x)。或者更好的是,不要定义这些,因为这只是浪费您的系统 RAM。就像它这样做的唯一原因是因为 append 将切片描述符作为一个值处理,在操作完成后返回一个新的。然后他做了一些不一致的事情来使他的类型只不过是一个切片链使用指针的方法。 -
@evanmcdonnal:使用这样的自定义类型是完全有理由的。例如,查看 stdlib 中的
container/heap或sort包(它显示了您不需要需要指针的位置)。在整个 stdlib 中还有更多这样的自定义类型的示例,包括 map 和 func 类型。 -
Go 中没有引用类型。例如。 slice 不是引用类型,而 chanel 也不是引用类型。 Go 中最接近引用类型的类型是映射。停止使用“引用类型”真的很有帮助:没有。
标签: parameters go reference