douda5227 2019-01-16 23:20
浏览 37
已采纳

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

In this playground link I have created a contrived version of my code where I am creating a variable of type X based on an input string. The variable will be one of a handful of types and implement an interface.

The code currently compiles and provides the correct result, however it strikes me as quite verbose and I'm trying to find if there is a shorthand approach to the result I'm achieving. The example has 3 types (dog, cat & bird) that implement the interface (animal), however my actual code will have up to 40 types in this switch statement.

The reason I am using this code is when retrieving results form a DBMS, I'm trying to use a generic load method that, when combined with sqlx, loads the database table into the correct struct based on the input string. I have entire control over the application and can change the input string to another type if required.

Code from playground link:

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条回答 默认 最新

  • doujia4759 2019-01-16 23:54
    关注

    You can create a hashmap from "string" to "function that returns animal" but setting that up would be more verbose than the switch statement.

    Something like this (not tested)

    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
        }
    }
    

    But it's a lot more verbose than the switch statement and obscures what should otherwise be explicit and clear.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?