为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Go 1.18 中访问泛型结构中的共享字段?我收到错误“类型 t 没有字段或方法

如何在 Go 1.18 中访问泛型结构中的共享字段?我收到错误“类型 t 没有字段或方法

Go
慕哥6287543 2022-11-23 16:00:45

我有两个结构,它们具有一些相同的字段名称和类型:


type JOURNAL_TAG struct {

    DATE_START            time.Time

    DATE_END              time.Time

    ENTRY_NUMBER          uint

    VALUE                 float64

}


type INVENTORY_TAG struct {

    DATE_START   time.Time

    DATE_END     time.Time

    PRICE        float64

    QUANTITY     float64

    ACCOUNT_NAME string

}

我有一个访问公共字段的函数,该字段DATE_START应该对这些类型的切片进行排序:


func sort_by_time[t JOURNAL_TAG|INVENTORY_TAG](slice []t, is_ascending bool) {

    sort.Slice(slice, func(i, j int) bool {

        return slice[i].DATE_START.After(slice[j].DATE_START) == is_ascending

    })

}

运行go build报编译错误:


slice[i].DATE_START undefined (type t has no field or method DATE_START)

我想使用泛型对这两种类型的切片进行排序,可以吗?


我正在使用 1.18。


查看完整描述

2 回答

?
沧海一幻觉

TA贡献1550条经验 获得超5个赞

来自Go 1.18 发行说明:


Go 编译器不支持访问结构字段 xf,其中 x 是类型参数类型,即使类型参数的类型集中的所有类型都有字段 f。我们可能会在 Go 1.19 中移除此限制。


例如,您可以向返回 DATE_START 字段的每个结构添加一个DateStart() time.Time方法,然后如果您想使用泛型,则将该方法用作类型约束的一部分。


也就是说,您不需要针对此特定问题的泛型。即使没有泛型,您也可以定义一个接口:


type SomeInterface interface {

    DateStart() time.Time

}

然后排序:


items := []SomeInterface{

    INVENTORY_TAG{...},

    INVENTORY_TAG{...},

}

sort.Slice(items, func(i, j int) bool { return items[i].DateStart().Before(items[j].DateStart()) })


查看完整回答
反对 回复 2022-11-23
?
MMMHUHU

TA贡献1555条经验 获得超8个赞

在这种情况下最好使用接口实现,但如果你想尝试泛型,你可以这样做:


package main


type JOURNAL_TAG struct {

    DATE_START            time.Time

    DATE_END              time.Time

    ENTRY_NUMBER          uint

    VALUE                 float64

}


type INVENTORY_TAG struct {

    DATE_START   time.Time

    DATE_END     time.Time

    PRICE        float64

    QUANTITY     float64

    ACCOUNT_NAME string

}


type hasDateInterface interface {

    DateStart() time.Time

}


func (j JOURNAL_TAG) DateStart(){

   return j.DATE_START

}


func (i INVENTORY_TAG) DateStart(){

   return i.DATE_START

}


func sort_by_time[t hasDateInterface](slice []t, is_ascending bool) {

    sort.Slice(slice, func(i, j int) bool {

        return slice[i].DATE_START.After(slice[j].DateStart()) == is_ascending

    })

}


试过 https://go.dev/play/p/Xak4uzCNhE-


查看完整回答
反对 回复 2022-11-23

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信