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

使用地图时出现 1.18 通用编译错误。使用结构键在地图上复制

使用地图时出现 1.18 通用编译错误。使用结构键在地图上复制

Go
回首忆惘然 2022-11-28 14:39:43
我实现了一个基于泛型的 Set,一切正常,直到我使用 struct 作为 Set 元素而不是基类型。我有一个编译错误。去版本:go version go1.18 windows/amd64下面的代码在功能上不符合要求AddSet。package mainimport (    "fmt"    "golang.org/x/exp/maps")type Key struct {    A, B int}func main() {    s := SetOf(        Key{1, 1},        Key{2, 2},        Key{3, 3},    )    s.AddSet(SetOf(        Key{3, 3},        Key{4, 4},        Key{5, 5},    ))    fmt.Println(s)}type Set[T comparable] map[T]struct{}func SetOf[T comparable](vs ...T) Set[T] {    s := Set[T]{}    for _, v := range vs {        s[v] = struct{}{}    }    return s}func (s Set[T]) AddSet(another Set[T]) {    maps.Copy(s, another)}运行时:> go run .\main.go# command-line-arguments.\main.go:19:10: cannot use &.autotmp_29 (type *struct { A int; B int }) as type *Key in argument to runtime.mapassign<autogenerated>:1: cannot use &.autotmp_12 (type *struct { A int; B int }) as type *Key in argument to runtime.mapassign如果Key只有1个字段,则可以编译成功。如果我使用for v := range another { s[v]=struct{}{} },它可以编译成功。我觉得很奇怪,有人可以解释一下吗?
查看完整描述

1 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

看起来像这个编译器错误。它在 Go 1.19 中得到修复并向后移植到 Go 1.18.2。


如果您使用的是旧版本,我建议maps您像您已经尝试过的那样,简单地放弃软件包并手动执行操作。这只是一个简单的循环:


func (s Set[T]) AddSet(another Set[T]) {

    for k := range another {

        s[k] = struct{}{}

    }

}

@icza 将命名映射类型显式转换为其基础类型的注释也有效:


maps.Copy(map[T]struct{}(s), another)

如果您使用需要多个映射类型参数(具有相同约束)的函数,如maps.Equalor maps.EqualFunc,您必须转换两个参数:


func (s Set[T]) Compare(another Set[T]) bool {

    // signature is Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool

    return maps.Equal(map[T]struct{}(s), map[T]struct{}(another))

}

似乎用 len >= 2 的数组实例化的参数化映射类型也重现了崩溃。


查看完整回答
反对 回复 2022-11-28
  • 1 回答
  • 0 关注
  • 153 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号