【发布时间】:2014-01-08 14:29:08
【问题描述】:
我很困惑为什么这段代码不起作用:
package main
import (
"fmt"
"sort"
)
type T [2]int
func (t T) Len() int { return len(t) }
func (t T) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
func (t T) Less(i, j int) bool { return t[i] < t[j] }
func main() {
var x = [2]int{1, 0}
fmt.Println(x)
sort.Sort(T(x))
fmt.Println(x)
}
它输出(不正确):
[1 0]
[1 0]
将 T 的类型更改为 slices 是正确的。
【问题讨论】:
-
IMO,Swap 不会对接收者做任何事情,即
t := T(x) t.Swap(0, 1)不会造成任何影响。 -
Everything in Go is passed (and assigned) by value,数组也不例外。切片具有所谓的“引用语义”,这意味着它们的值包含对底层数据存储的引用,因此将切片传递给函数复制切片值但复制共享 i> 具有原始切片值的底层数据存储*。
-
kostix,您的链接提到“Go 中的所有内容都是按值传递的,但是有三个内置的“引用类型”也按值传递,但在内部它们包含对单独维护的数据的引用结构:地图、切片、通道”。但我在官方Go spec 中找不到任何提及。我错过了什么吗?谢谢。
-
@epsylon,不,我想你没有。我对此的看法是,规范是一种法律文件:它可能过于简洁,但作为交换,它是最小的——它只定义了形式上重要的内容。这里调用了值具有引用语义的类型的概念,以帮助人们理解为什么他们会以他们的行为方式行事;它们很可能在语言中正式不存在,但它们确实存在。
-
@epsylon,您也可以从另一个角度看待这个问题:规范没有解释“为什么”,也没有描述它定义的概念与其他规范中的类似概念的行为方式有何不同。比如说,如果映射的分配克隆了这些映射,那么规范应该会明确定义,但由于它们没有,规范对此保持沉默。
标签: go