gpt4 book ai didi

go - 在 GoLang 中为多种类型使用指向函数的指针

转载 作者:行者123 更新时间:2023-12-05 03:17:56 28 4
gpt4 key购买 nike

我有很多(20 多种)以下形式的“枚举类型”。我想要做的是在一个结构中按名称列出所有枚举类型(见下文)和一个指向返回所有类型的函数的指针。请参阅下面的缩略示例。

package main

type Fruit int

const (
unknownFruit Fruit = iota // must be first
Apple
Banana
fruitDone
)

func FruitTypes() []Fruit {
var res []Fruit
for typ := unknownFruit + 1; typ < fruitDone; typ++ {
res = append(res, typ)
}
return res
}

type Car int

const (
unknownCar Car = iota // must be first
BMW
Mercedes
doneCar
)

func CarTypes() []Car {
var res []Car
for typ := unknownCar + 1; typ < doneCar; typ++ {
res = append(res, typ)
}
return res
}


func main() {
enumTypes := []struct {
Name string
Length int
ConvertFunc func(int) string
}{
{Name: "Fruit", Length: int(doneFruit), ConvertFunc: ConvertEnum[Fruit]},
{Name: "Car", Length: int(doneCar), ConvertFunc: ConvertEnum[Car]},
}

for _, enumType := range enumTypes {
fmt.Println(enumType.Name)
for i := 0; i < enumType.Length; i++ {
fmt.Printf(" -- %s", enumType.ConvertFunc(i))
}
}
}

func ConvertEnum[T any](raw int) string {
return fmt.Sprintf("%v", T(raw)) // #2 - This will not convert
}

不幸的是,我似乎无法正确声明函数指针。正确的返回类型是什么?

(顺便说一句,有没有办法为这些枚举类型声明一个接口(interface)和/或使用泛型,这样我就不必使用 FruitType()、CarType()、PetType().. .

=================

更新 - 感谢@Woody1193,我觉得我更接近了。我现在使用的是枚举是连续数字这一事实,所以除了类型之外我真的不需要传递任何细节,所以我可以将它强制转换回循环中(参见上面的标记 #1)。

但是,在上面,我得到:

./main.go:55:64: cannot use EnumType[Fruit] (value of type func(done Fruit) []Fruit) as type func() []int in struct literal
./main.go:56:60: cannot use EnumType[Car] (value of type func(done Car) []Car) as type func() []int in struct literal
./main.go:62:43: too many arguments in call to typ.TypeFunction

=================

更新 #2 - 我尝试换个角度,只传入转换函数,将其从结构中取出。 (看上面)。但是现在它不让我施放它:(

./main.go:68:31: cannot convert raw (variable of type int) to type T

最佳答案

你在这里遇到的问题是 CarFruit 实际上都不是整数,所以 TypesFunction 不会接受 CarTypesFruitTypes。泛型在这种情况下不起作用,因为声明此类对象的一部分将要求它们都具有相同的类型参数,这意味着您的代码仍然不起作用。

因此,您最好的选择是修改 CarTypesFruitTypes,使它们具有相同的签名,func() []int:

func FruitTypes() []int {
var res []int
for typ := unknownFruit + 1; typ < fruitDone; typ++ {
res = append(res, typ)
}
return res
}

func CarTypes() []int {
var res []int
for typ := unknownCar + 1; typ < doneCar; typ++ {
res = append(res, typ)
}
return res
}

当然,这意味着当您需要特定类型的枚举时,您必须使用类型转换,但代码会起作用。

顺便说一句,您可以使用泛型来生成函数本身:

func EnumType[T ~int](done T) []int {
var res []int
for typ := T(1); typ < done; typ++ {
res = append(res, typ)
}

return res
}

func ConvertEnum[T ~int](raw ...int) []T {
res := make([]T, len(raw))
for i, typ := range raw {
res[i] = T(typ)
}

return res
}

enumTypes := []struct {
Name string
TypesFunction func() []int
}{
{Name: "Fruit", TypesFunction: EnumType[Fruit]},
{Name: "Car", TypesFunction: EnumType[Car]},
}

关于go - 在 GoLang 中为多种类型使用指向函数的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73888563/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com