英文:
Go sorts slice correctly, but doesn't sort array
问题
我对这段代码为什么不起作用感到困惑:
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的类型更改为切片会得到正确的结果。
英文:
I'm puzzled as why this code doesn't work:
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)
}
It outputs (incorrectly):
[1 0]
[1 0]
Changing the type of T to slices does the correct thing.
答案1
得分: 8
切片本质上是引用类型,意味着切片头部包含对支持数组的指针,因此可以在没有指针接收器的情况下进行修改。而数组不是引用类型,在调用方法时会完全复制。
为了在数组中实现这个功能,你需要将所有内容都改为使用指针,所以你的代码可能如下所示:
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 = &T{1, 0}
fmt.Println(*x)
sort.Sort(x)
fmt.Println(*x)
}
注意,我将 T([2]int{1, 0})
改为 &T{1, 0}
,并且在调用 sort.Sort
时传递了指针 x
的地址 &x
。
英文:
Slices are inherently reference types, meaning the slice header contains a pointer to the backing array, so they can be mutated without a pointer receiver. Arrays not being a reference type, are copied in full when calling your methods.
In order to do this with an array you need to change everything to use pointers, so your code might look something like:
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 = T([2]int{1, 0})
fmt.Println(x)
sort.Sort(&x)
fmt.Println(x)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论