Go语言可以正确地对切片进行排序,但不能对数组进行排序。

huangapple go评论67阅读模式
英文:

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 (
    &quot;fmt&quot;
    &quot;sort&quot;
)

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] &lt; 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 (
	&quot;fmt&quot;
	&quot;sort&quot;
)

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] &lt; t[j] }

func main() {
	var x = T([2]int{1, 0})
	fmt.Println(x)
	sort.Sort(&amp;x)
	fmt.Println(x)
}

huangapple
  • 本文由 发表于 2014年1月8日 22:29:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/20998394.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定