Is there a way to elide type of a composite literal by inferring types based on the type parameter of function in go?

huangapple go评论76阅读模式
英文:

Is there a way to elide type of a composite literal by inferring types based on the type parameter of function in go?

问题

type Foo struct {
    a    string
    b    int
}

type Bar[K Foo|string] struct {
    c    K
    d    string
}

func someRandomFunc (x []Bar[Foo], y []Bar[string]) {
    ///do something
}

someRandomFunc([]Bar[Foo]{{Foo{"A", 1}, "a"}, {Foo{"B", 1}, "b"}}, []Bar[string]{{{"C"}, "c"}, {{"D"}, "d"}})

在上面的代码中,为什么Go不能从函数参数中推断类型?我是否必须每次都在自定义类型前加上前缀?为什么我不能像下面这样做?

someRandomFunc({{{"A", 1}, "a"}, {{"B", 1}, "b"}}, {{{"C"}, "c"}, {{"D"}, "d"}})

从约束的泛型类型中推断类型

Go 也无法从约束的泛型类型中推断类型(如果约束的泛型类型是原始类型如string,它会进行推断,但对于自定义类型则不会)。

someRandomFunc([]Bar[Foo]{{{ "A", 1}, "a"}, {{ "B", 1}, "b"}}, []Bar[string]{{{"C"}, "c"}, {{"D"}, "d"}})

从切片中的前一个兄弟元素推断类型

Go 甚至无法从切片中的前一个兄弟元素推断类型。

someRandomFunc([]Bar[Foo]{{Foo{"A", 1}, "a"}, {{"B", 1}, "b"}, {{"C", 1}, "c"}}, []Bar[string]{{{"D"}, "d"}, {{"E"}, "e"}, {{"F"}, "f"}})

上述任何一种情况是否有任何解决方法?

英文:
type Foo struct {
    a    string
    b    int
}

type Bar[K Foo|string] struct {
    c    K
    d    string
}

func someRandomFunc (x []Bar[Foo], y []Bar[string]) {
    ///do something
}

someRandomFunc([]Bar[Foo]{{Foo{"A", 1}, "a"}, {Foo{"B", 1}, "b"}}, []Bar[string]{{{"C"}, "c"}, {{"D"}, "d"}})

In the above code why isnt go infering type from the function argument? Do I have to prefix each time the custom type? Why can't I do something like below?

someRandomFunc({{{"A", 1}, "a"}, {{"B", 1}, "b"}}, {{{"C"}, "c"}, {{"D"}, "d"}})

Inferring type from the constrained generic type

Go is not inferring the type from the constrained generic type as well (which it does infer if the constrained generic type is a primite types like string but not for custom types).

someRandomFunc([]Bar[Foo]{{{"A", 1}, "a"}, {{"B", 1}, "b"}}, []Bar[string]{{{"C"}, "c"}, {{"D"}, "d"}})

Inferring type from the sibling inside the slice

Go does not even infer the type from the previous sibling inside the slice

someRandomFunc([]Bar[Foo]{{Foo{"A", 1}, "a"}, {{"B", 1}, "b"}, {{"C", 1}, "c"}}, []Bar[string]{{{"D"}, "d"}, {{"E"}, "e"}, {{"F"}, "f"}})

Is any of the above possible with any workaround?

答案1

得分: 1

在Go 1.19.4中,只有在数组、切片和映射的情况下才能省略复合字面量中的类型。对于结构体,类型字段是必需的,不能省略。

示例

1. 数组和切片 - 可行

type Foo struct {
    a    string
    b    int
}

var a []Foo = []Foo{{"A", 1}, {"B", 2}}

2. 映射 - 可行

type Foo struct {
    a    string
    b    int
}

var a map[string]Foo = map[string]Foo{"a": {"A", 1}, "b": {"B", 2}}

3. 结构体 - 不可行

type Foo struct {
    a    string
    b    Bar
}

type Bar struct {
    c    string
    d    int
}

var a []Foo = []Foo{{"A", Bar{"a", 1}}, {"B", Bar{"b", 2}}}

在上面的示例中可以注意到,类型字段Bar没有被省略。此外,由于从Go 1.19.4开始不支持结构体的类型省略,无论是否约束了泛型类型,类型省略都不是一个选项。

英文:

Type elisions in composite literals as of Go 1.19.4 is possible only in case of arrays, slices and maps. For structs type fields are mandatory and cannot be omitted.

Example

1. Arrays and Slices - Possible

type Foo struct {
    a    string
    b    int
}

var a []Foo = []Foo{{"A", 1}, {"B", 2}}

2. Maps - Possible

type Foo struct {
    a    string
    b    int
}

var a Map[string]Foo = Map[string]Foo{"a": {"A", 1}, "b": {"B", 2}}

3. Struct - Not possible

type Foo struct {
    a    string
    b    Bar
}

type Bar struct {
    c    string
    d    int
}

var a []Foo = []Foo{{"A", Bar{"a", 1}}, {"B", Bar{"b", 2}}}

In the above example it can be noted that type field Bar is not omitted. Further since go as of 1.19.4 doesn't support type elision for structs, type elision is not an option whether or not a generic type is constrained or otherwise.

huangapple
  • 本文由 发表于 2022年12月18日 13:41:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/74839331.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定