在Golang中,在一个函数中返回不同结果值中的一个的正确方法是什么?

mklgxw1f  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(122)

我是Go的新手,希望能从更有经验的开发者那里得到一些见解。
在我的main函数中,我调用了一个'Prepare'函数,它将枚举作为参数。枚举是三个选项之一:A、B、C.在函数“PrepareData”内部,具有基于枚举类型调用对应结构的三个准备方法之一的开关情况。这些方法中的每一个都返回不同的结构体作为结果(typeA、typeB、typeC)。但是,“Prepare”函数的返回值应该是什么?
什么是最干净的ideomatic方法来做到这一点?我知道我可以从'Prepare'函数返回一个emty接口,或者用一个公共方法创建一个接口并返回它,但这些选项对我来说似乎并不“干净”。我说错了吗?我想尽可能地保持强类型,并在'Prepare'函数的结果中有一个具体类型。泛型或类型asserton/casting可以解决这个问题吗?如有任何建议,将不胜感激。
下面是一些示例代码:

type DataType int

const (
    A DataType = iota
    B
    C
)
func main() {
    dataType := C // Type will change in run time. Just an examlpe
    result := Prepare(dataType)
    fmt.Println(result)
}
func Prepare(dataType DataType) interface{} { // return value in the question
    switch dataType {
    case A:
        return TypeA{}.Prepare()
    case B:
        return TypeB{}.Prepare()
    case C:
        return TypeC{}.Prepare()
    default:
        return nil
    }
}
type TypeA struct{}

func (t TypeA) Prepare() *TypeA {
    return &TypeA{}
}
type TypeB struct{}

func (t TypeB) Prepare() *TypeB {
    return &TypeB{}
}
type TypeC struct{}

func (t TypeC) Prepare() *TypeC {
    return &TypeC{}
}
mkshixfv

mkshixfv1#

Go不是TypeScript,它的灵活类型相当有限。您的选择是:

  • 返回三个不同的专用函数,正如@Volker在评论中已经建议的那样。这是你能从围棋中得到的唯一“真实的”的类型安全。我真的看不出一个函数有什么好处,它的行为完全不同,这取决于它的输入值。如果有共享代码,将其提取到单独的实用程序函数中。
  • 返回interface{}/any
  • 返回如下所示的struct,您可以稍后检查哪个值不是nil。这是相当臃肿。
type Result struct {
  ResultA *TypeA
  ResultB *TypeB
  ResultC *TypeC
}
  • 如果只是三个不同的类型(不会变得更多),则以func Prepare(dataType DataType) (*TypeA, *TypeB, *TypeC) {...的方式返回它们,并检查哪个不是nil

我个人会使用三个专用功能,或者使用interface{}/any。请注意,如果您选择后者,则有一个相当直接的模式来处理type switches的不同预期类型:

switch v:=result.(type) {
case TypeA, *TypeA:
    v.SpecificTypeAFunction()
case TypeV, *TypeB:
    v.SpecificTypeBFunction()
case TypeC, *TypeC:
    v.SpecificTypeCFunction()
default:
    panic(fmt.Errorf("result is of type %T, which is not supported yet", result))
}

相关问题