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

我实现了一个基于泛型的 Set,一切正常,直到我使用 struct 作为 Set 元素而不是基类型。我有一个编译错误。


去版本:go version go1.18 windows/amd64


下面的代码在功能上不符合要求AddSet。


package main


import (

    "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{}{} },它可以编译成功。

我觉得很奇怪,有人可以解释一下吗?


回首忆惘然
浏览 154回答 1
1回答

阿波罗的战车

看起来像这个编译器错误。它在 Go 1.19 中得到修复并向后移植到 Go 1.18.2。如果您使用的是旧版本,我建议maps您像您已经尝试过的那样,简单地放弃软件包并手动执行操作。这只是一个简单的循环:func (s Set[T]) AddSet(another Set[T]) {&nbsp; &nbsp; for k := range another {&nbsp; &nbsp; &nbsp; &nbsp; s[k] = struct{}{}&nbsp; &nbsp; }}@icza 将命名映射类型显式转换为其基础类型的注释也有效:maps.Copy(map[T]struct{}(s), another)如果您使用需要多个映射类型参数(具有相同约束)的函数,如maps.Equalor maps.EqualFunc,您必须转换两个参数:func (s Set[T]) Compare(another Set[T]) bool {&nbsp; &nbsp; // signature is Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool&nbsp; &nbsp; return maps.Equal(map[T]struct{}(s), map[T]struct{}(another))}似乎用 len >= 2 的数组实例化的参数化映射类型也重现了崩溃。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go