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