我实现了一个基于泛型的集合,一切正常,直到我使用struct作为Set元素而不是基类型。我犯了一个顺从错误。
go版本: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.mapassignKey只有一个字段,则可以成功编译。for v := range another { s[v]=struct{}{} },可以成功地编译它。我觉得很奇怪,有人能解释一下吗?
发布于 2022-04-07 13:08:42
看起来像此编译器错误。它固定在Go 1.19中,并支持Go 1.18.2。
如果您使用的是旧版本,我建议您放弃maps包,手工操作,就像您已经尝试过的那样。这只是一个简单的循环:
func (s Set[T]) AddSet(another Set[T]) {
for k := range another {
s[k] = struct{}{}
}
}@icza关于显式地将命名的map类型转换为其基础类型的注释也有效:
maps.Copy(map[T]struct{}(s), another)如果您使用的函数需要一个以上的映射类型参数(具有相同的约束),如maps.Equal或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的数组实例化参数化的映射类型的。
https://stackoverflow.com/questions/71781676
复制相似问题