如何在go中排列不同结构类型的列表
我和Go一起工作才几天。我定义了一小部分不同的结构类型,每个结构类型都包含一个日期 不知何故,我需要按日期顺序处理这些结构,但这种顺序必须跨越多个不同的结构类型。在动态类型语言(如Python)中,只需创建按日期键入的所有对象的散列(如果列表不是唯一的,则创建列表散列)就很容易了。在C语言中,我可以使用指针的并集或void*。但我被困在如何在Go中实现这一点上 我想我可以保留每种类型的排序列表,并在运行时进行手动合并排序。看起来很糟糕 我所读到的关于处理这种情况的内容似乎指向使用接口,但我不知道在这种情况下如何使用它们 为了便于讨论,我们假设我有这样的东西:如何在go中排列不同结构类型的列表,go,Go,我和Go一起工作才几天。我定义了一小部分不同的结构类型,每个结构类型都包含一个日期 不知何故,我需要按日期顺序处理这些结构,但这种顺序必须跨越多个不同的结构类型。在动态类型语言(如Python)中,只需创建按日期键入的所有对象的散列(如果列表不是唯一的,则创建列表散列)就很容易了。在C语言中,我可以使用指针的并集或void*。但我被困在如何在Go中实现这一点上 我想我可以保留每种类型的排序列表,并在运行时进行手动合并排序。看起来很糟糕 我所读到的关于处理这种情况的内容似乎指向使用接口,但我不知道
type A struct {
Date string
Info string
}
type B struct {
Date string
Info int
}
(虽然实际上有更多的结构,而且它们更复杂,有多个字段),只需按日期顺序打印每个结构(未排序)数组的内容
是否有办法创建指向非统一对象类型的列表(日期、指针)对
根据以下第一条建议:
package main
import "fmt"
type A struct {
Date string
Info string
}
func (x *A) GetDate() string {
return x.Date
}
type B struct {
Date string
Info int
}
func (x *B) GetDate() string {
return x.Date
}
type Dater interface {
GetDate() string
}
type Daters []Dater
func (s Daters) Len() int { return len(s) }
func (s Daters) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type ByDate struct{ Daters }
func (s ByDate) Less(i, j int) bool {
return s.Daters[i].GetDate() < s.Daters[j].GetDate()
}
func main() {
// lista and listb are just examples. They really come from elsewhere
lista := []A{{"2012/08/01", "one"}, {"2012/08/03", "three"}}
listb := []B{{"2012/08/02", 2}, {"2012/08/04", 4}}
x := make([]Dater, len(lista) + len(listb))
index := 0
for i := range(lista) {
x[index] = &lista[i]
index++
}
for i := range(listb) {
x[index] = &listb[i]
index++
}
sort.Sort(ByDate{x})
for _,v := range(x) {
fmt.Printf("%#v\n", v)
}
}
主程序包
输入“fmt”
类型A结构{
日期字符串
信息字符串
}
func(x*A)GetDate()字符串{
报税表x.日期
}
B型结构{
日期字符串
信息整型
}
func(x*B)GetDate()字符串{
报税表x.日期
}
类型日期器接口{
GetDate()字符串
}
类型日期器[]日期器
func(s日期)Len()int{return Len(s)}
func(s日期者)Swap(i,j int){s[i],s[j]=s[j],s[i]}
类型ByDate结构{Daters}
func(s ByDate)减去(i,j int)bool{
返回s.Daters[i].GetDate()
真管用!所以界面的基本用法很好,我开始理解了
界面稍微好一点-谢谢
注意:x的创建非常难看。我看不到更干净/更惯用的方法了?用方法(比如返回日期的getDate())定义接口(比如Date)。然后让所有结构(A、B、C)实现接口。然后可以定义use[]Dated来保存类型值
您可能希望检查包的“时间”和“排序”以简化实现 您可能可以使用
您可以定义一个只包含日期的结构,然后将其嵌入其他结构中。这样,您只需实现GetDate()一次。您还可以随时扩展日期结构,而无需修改其他结构
package main
type Dater interface {
GetDate() string
}
type Date struct {
Date string
}
func (d *Date) GetDate() string {
return d.Date
}
type A struct {
Date
Info string
}
type B struct {
Date
Info []byte
}
type C struct {
Date
Info int32
}
现在,您可以在A、B和C上调用GetDate()。非常小的命名nit:一个名为“Dater”的接口和一个名为“Date()”的方法将更惯用Go命名。@uriel在这种情况下,您将如何处理名为Date的字段这一事实?惯用的解决方案是什么?谢谢-效果很好。我让它工作(见更新的问题),即使它不是最漂亮的;-)事实证明我不能这么做——因为隐藏在我给你的简化背后的原因。我正在从XML解析结构,XML模块将填充原始结构-这些不同的日期字段需要不同的标记才能正确填充。总的来说,你说的话似乎很管用!