Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 有没有办法避免实现结构切片的完整sort.Interface?_Sorting_Interface_Go - Fatal编程技术网

Sorting 有没有办法避免实现结构切片的完整sort.Interface?

Sorting 有没有办法避免实现结构切片的完整sort.Interface?,sorting,interface,go,Sorting,Interface,Go,如果我在Go中有一个结构数组/切片,并希望使用sort包对其进行排序,那么在我看来,我需要实现包含3种方法的整个排序接口: 莱恩 交换 少 似乎无论数组中的结构类型是什么,Len和Swap都应该始终具有相同的实现 有没有办法避免每次都使用工具Len和Swap,或者这只是由于Go中缺少泛型而造成的限制?您自己的答案是正确的。对于数组或切片,Len()和Swap()的实现非常简单。像len()一样,Go可以在这里提供本机swap()。但是现在使用的接口也可以用于更复杂的数据结构,如BTrees。

如果我在Go中有一个结构数组/切片,并希望使用sort包对其进行排序,那么在我看来,我需要实现包含3种方法的整个排序接口:

  • 莱恩
  • 交换
似乎无论数组中的结构类型是什么,Len和Swap都应该始终具有相同的实现


有没有办法避免每次都使用工具Len和Swap,或者这只是由于Go中缺少泛型而造成的限制?

您自己的答案是正确的。对于数组或切片,Len()和Swap()的实现非常简单。像len()一样,Go可以在这里提供本机swap()。但是现在使用的接口也可以用于更复杂的数据结构,如BTrees。它仍然允许Sort()函数工作(就像我的并行快速排序一样,它使用相同的排序接口)。

如果要在同一切片类型上实现多个不同的比较操作,可以使用嵌入来避免每次重新定义Len和Swap。您还可以使用此技术向排序中添加参数,例如,根据某些运行时值进行反向排序或不进行排序

e、 g

主程序包
进口(
“排序”
)
T型结构{
福因特
Bar int
}
//TVector是我们的基本向量类型。
TVector[]T型
func(v TVector)Len()int{
返回长度(v)
}
函数(v TVector)交换(i,j int){
v[i],v[j]=v[j],v[i]
}
//默认比较。
函数(v向量)减去(i,j int)布尔{
返回v[i].Foo
虽然这是一个老问题,但我想指出 这个 包裹 但仅作为一个示例或概念证明,我不建议实际使用此选项(文档中有“gross”一词):

它使用粗略的低级操作,只需较少的函数即可轻松对任意切片进行排序,而无需使用Len和Swap操作定义新类型

在实际的代码中,我发现只需执行以下操作就完全是琐碎的、快速的、简短的、可读的和不分散注意力的:

type points []point

func (p []points) Len() int      { return len(p) }
func (p []points) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p []points) Less(i, j int) bool {
        // custom, often multi-line, comparison code here
}
这里,
gofmt
坚持在
type
func
行之间有一个空行 但是,它没有问题 多个单行函数,无空行 它很好地排列了功能体。 我发现这是一个很好的可读性很强的紧凑形式

关于你的评论:

似乎无论[slice]中的结构类型是什么,Len和Swap都应该始终具有相同的实现

就在前几周,我需要一种排序方法,将一个片段中的元素对保持在一起(用于
strings.NewReplacer
)的输入,这需要一个简单的变化,如:

type pairByLen []string

func (p pairByLen) Len() int           { return len(p) / 2 }
func (p pairByLen) Less(i, j int) bool { return len(p[i*2]) > len(p[j*2]) }
func (p pairByLen) Swap(i, j int) {
        p[i*2], p[j*2] = p[j*2], p[i*2]
        p[i*2+1], p[j*2+1] = p[j*2+1], p[i*2+1]
}
类似于github.com/bradfitz/slice中的接口不支持这一点。 同样,我发现这种布局简单、紧凑、易读。
尽管(在这种情况下可能更为如此),但其他人可能不同意。

如果您希望对切片进行排序(对于切片,Len和Swap始终具有相同的实现),则排序包现在有一个只需要较少实现的功能:


非常有趣。我想知道如何在同一切片类型上使用多个排序。
type pairByLen []string

func (p pairByLen) Len() int           { return len(p) / 2 }
func (p pairByLen) Less(i, j int) bool { return len(p[i*2]) > len(p[j*2]) }
func (p pairByLen) Swap(i, j int) {
        p[i*2], p[j*2] = p[j*2], p[i*2]
        p[i*2+1], p[j*2+1] = p[j*2+1], p[i*2+1]
}