GO 中如何做到“读不同的配置,加载不同的类” - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Morriaty
V2EX    Go 编程语言

GO 中如何做到“读不同的配置,加载不同的类”

  •  
  •   Morriaty 2018-01-30 19:28:01 +08:00 2426 次点击
    这是一个创建于 2861 天前的主题,其中的信息可能已经有所发展或是发生改变。

    python 的逻辑大致如下,但在 go 中不知道怎么做

    class A(object): def run(self): pass class B(object): def run(self): pass all_classes = {"a": A, "b": B} for class_type, args in read_config("config_file"): instance = all_classes[class_type](**args) # 或者 instance = getattr(sys.modules[__name__], class_type.upper()) instance.run() 

    现在能想到的就是写一堆的 if else,然后返回一个 interface{},有更合理的方式吗?

    func LoadClass(class_type string, args map[string]string) interface{} { if class_type == "a" { ... } else if ... } 
    16 条回复    2018-02-23 13:21:05 +08:00
    hjc4869
        1
    hjc4869  
       2018-01-30 19:28:39 +08:00 via iPhone
    map
    Morriaty
        2
    Morriaty  
    OP
       2018-01-30 19:32:12 +08:00
    @hjc4869 可能我理解有误,我要的是 map 里能存 struct 的类,而不是 struct 的实例
    naiba
        3
    naiba  
       2018-01-30 19:32:13 +08:00 via Android
    reflect
    rrfeng
        4
    rrfeng  
       2018-01-30 19:33:24 +08:00 via Android
    写一个 newstruct 方法,用 map string func 存起来。
    rrfeng
        5
    rrfeng  
       2018-01-30 19:35:23 +08:00
    感觉应该从需求上去重新考虑一下。

    如果 A 和 B 完全没任何关系,为什么要这样写?如果两者很类似,是不是有更好的数据结构?
    douglarek
        6
    douglarek  
       2018-01-30 20:21:32 +08:00 via iPhone
    定义一个接口 Runner 里面有一个方法 run,让不同的 struct 去实现 Runner 然后 loadclass 返回 Runner
    table cellpadding="0" cellspacing="0" border="0" width="100%"> Archangel_SDY
        7
    Archangel_SDY  
       2018-01-30 23:21:44 +08:00
    map 里存 factory 函数.
    looplj
        8
    looplj  
       2018-01-30 23:41:21 +08:00   1
    Go 不能通过一个字符串反射出一个对象,所以先要将一个 struct 的构造方式注册。
    我们用的是 Model 接口有一个 New 方法,直接返回 new(Model),注册 model 到 factory,然后 factory 通过字符串返回 model 实例。
    Morriaty
        9
    Morriaty  
    OP
       2018-01-31 10:11:39 +08:00
    @rrfeng
    @douglarek
    目前就是按 type Runner interface{}这种方式做的,但不知道怎么返回一个 default 的空 interface,只能极其愚蠢的又实现了一个 type RunDefault struct {}
    douglarek
        10
    douglarek  
       2018-01-31 10:14:49 +08:00 via iPhone
    @Morriaty 那不可能啊 你定义的不是空接口肯定没法返回默认非空
    Morriaty
        11
    Morriaty  
    OP
       2018-01-31 10:32:09 +08:00
    @ZSeptember 注册 model 到 factory,这点能说详细点,或者给个示例代码吗?
    iRiven
        12
    iRiven  
       2018-01-31 10:43:17 +08:00 via Android
    你姿势不对。
    looplj
        13
    looplj  
       2018-01-31 10:56:07 +08:00
    @Morriaty new 一个空的 model。。这一步是没法省的。
    fortunezhang
        14
    fortunezhang  
       2018-01-31 10:58:41 +08:00
    简单点就是用 map
    复杂点就上设计模式。
    nekoyaki
        15
    nekoyaki  
       2018-02-23 13:14:38 +08:00   1
    你的思路不对,go 里不是这么考虑问题的,我提几个提示。
    1、golang 不是面向对象的语言,不要套用面向对象语言的设计模式。
    2、golang 如果想要实现类似根据不同的类实现多个逻辑的需求,你需要把它转换成结构体来考虑。
    3、func 在 golang 里是一等结构,因此结构体上可以有一些成员,这些成员的类型,是特定类型的 func。
    4、读取配置文件后,如果是 A 情况,则把该成员赋值为方法 A,如果是 B 情况,则把该成员赋值为方法 B。
    nekoyaki
        16
    nekoyaki  
       2018-02-23 13:21:05 +08:00
    接上条,手滑发出去了……
    5、这样实例 A 的 run 方法和实例 B 的 run 方法就可以实现不同的逻辑。
    伪代码举例如下:
    ```
    type Person Struct {
    name string
    tell func()(xxx)
    }



    zhangxiaojie = Person{ "baohua", func()(xxx) { fmt.println("Mr. dong lianren ? ") } }
    jiangxiansheng = Person { "takumin", func()(xxx) { fmt.println("Hou wa! ") }}


    zhangxiaojie.tell()
    jiangxiansheng.tell()
    ```
    这样两个人都是 person 实例,但 tell 方法的逻辑是不同的,不需要在方法逻辑里面来暴力 if else。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5267 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 07:32 PVG 15:32 LAX 23:32 JFK 02:32
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86