是否有更惯用的方法根据输入来创建特定类型的变量?

时间:2019-01-16 23:20:20

标签: go

this playground link中,我创建了人为的代码版本,其中,我基于输入字符串创建了类型X的变量。变量将是少数几种类型之一,并实现一个接口。

当前代码可以编译并提供正确的结果,但是它使我感到非常冗长,因此我尝试查找是否有一种捷径来实现我的结果。该示例具有实现接口(动物)的3种类型(狗,猫和鸟),但是在此switch语句中,我的实际代码将多达40种类型。

我使用此代码的原因是从DBMS检索结果时,我试图使用一种通用加载方法,当与sqlx结合使用时,该方法将数据库表加载到基于输入字符串。我对应用程序拥有完全控制权,并且可以根据需要将输入字符串更改为另一种类型。

游乐场链接中的代码:

package main

import (
    "fmt"
)

type animal interface {
    call() string
}

type dog struct {
}

func (d *dog) call() string {
    return "Woof!"
}

type cat struct {
}

func (c *cat) call() string {
    return "Meow!"
}

type bird struct {
}

func (c *bird) call() string {
    return "Chirp!"
}

func main() {
    var animal animal
    animalType := "dog"
    switch animalType{
    case "dog":
        animal = new(dog)
    case "cat":
        animal = new(cat)
    case "bird":
        animal = new(bird)

1 个答案:

答案 0 :(得分:2)

您可以创建一个从“字符串”到“返回动物的函数”的哈希表,但设置起来会比switch语句更为冗长。

类似的东西(未经测试)

type AnimalCtor func() animal

var animalMap map[string]AnimalCtor

.....

func init() {
    animalMap["dog"] = func() animal { return &dog{} }
    animalMap["cat"] = func() animal { return &cat{} }
    animalMap["bird"] = func() animal { return &bird{} }
    .....
}

func createAnimalFromString(input string) animal {
    ctor, ok := animalMap[input]
    if ok {
        return ctor()
    } else {
        return nil
    }
}

但是它比switch语句冗长得多,并且掩盖了本应明确和清楚的内容。