doushan6692 2016-09-18 15:23
浏览 54
已采纳

Go中类似C ++模板的行为

For example I have two different structs Foo and Bar

struct Foo {...}
struct Bar {...}

and a lot of functions and other types built on them.

C++ flavor:

template<typename T>
struct Identified {
    T model;
    std::string id;
};

template<typename T>
Identified<T> GetIdentifiedModel(std::string id) {
    Identified<T> result;
    T.id = id;
    T.model.set(getSomeData(id));  // Common method for T
    return result;
}

How to implement these examples in Go?

For common methods, interfaces do the job but I don't see how to retrieve a specific type from an interface to declare it, return it or anything else and I can't handle copy/paste code anymore :)

Thanks !

Edit @Amd: https://ideone.com/rqpsQb

#include <string>
#include <iostream>

struct Foo {
    char c;
    void set(std::string s) {c = s[0];}; // We don't really care here
};
struct Bar {
    int n;
    void set(std::string s) {n = s.size();}; // We don't really care here
};

template<typename T>
struct Identified {
    T model;
    std::string id;
};

template<typename T>
Identified<T> GetIdentifiedModel(std::string id) {
    Identified<T> result;
    result.id = id;
    // Obviously shouldn't be ID but for the example
    result.model.set(id);  // Common method for T
    return result;
}

void assert(bool b) {
    if (b) std::cout << "OK" << std::endl;
    else std::cout << "There is a problem !" << std::endl;
};

int main() {
    auto fooWithID = GetIdentifiedModel<Foo>("foo id");
    auto barWithID = GetIdentifiedModel<Bar>("bar");
    assert (fooWithID.model.c == 'f');
    assert (barWithID.model.n == 3);
    return (0);
}
  • 写回答

1条回答 默认 最新

  • duanping5306 2016-09-18 16:44
    关注

    1- You may use

    fooWithID := GetIdentifiedModel("foo id", &Foo{})
    

    like this working sample ( try on The Go Playground):

    package main
    
    import "fmt"
    
    type Foo struct {
        c byte
    }
    
    func (t *Foo) set(s string) { t.c = s[0] }
    
    type Bar struct {
        n int
    }
    
    func (t *Bar) set(s string) { t.n = len(s) }
    
    type Identified struct {
        model T
        id    string
    }
    
    func GetIdentifiedModel(id string, t T) *Identified {
        result := &Identified{model: t}
        result.id = id
        result.model.set(id)
        return result
    }
    
    func assert(b bool) {
        if b {
            fmt.Println("OK")
        } else {
            fmt.Println("There is a problem !")
        }
    }
    
    func main() {
        fooWithID := GetIdentifiedModel("foo id", &Foo{})
        barWithID := GetIdentifiedModel("bar", &Bar{})
    
        assert(fooWithID.model.(*Foo).c == 'f')
        assert(barWithID.model.(*Bar).n == 3)
    }
    
    type T interface {
        set(string)
    }
    

    output:

    OK
    OK
    

    2- You may use (this is nice to read: Identified model Foo):

    fooWithID := GetIdentifiedModel("foo id", &Identified{model: &Foo{}})
    

    like this working sample ( try on The Go Playground):

    package main
    
    import "fmt"
    
    type Foo struct {
        c byte
    }
    
    func (t *Foo) set(s string) { t.c = s[0] }
    
    type Bar struct {
        n int
    }
    
    func (t *Bar) set(s string) { t.n = len(s) }
    
    type Identified struct {
        model T
        id    string
    }
    
    func GetIdentifiedModel(id string, result *Identified) *Identified {
        result.id = id
        result.model.set(id)
        return result
    }
    
    func assert(b bool) {
        if b {
            fmt.Println("OK")
        } else {
            fmt.Println("There is a problem !")
        }
    }
    
    func main() {
        fooWithID := GetIdentifiedModel("foo id", &Identified{model: &Foo{}})
        barWithID := GetIdentifiedModel("bar", &Identified{model: &Bar{}})    
        assert(fooWithID.model.(*Foo).c == 'f')
        assert(barWithID.model.(*Bar).n == 3)
    }
    
    type T interface {
        set(string)
    }
    

    output:

    OK
    OK
    

    See also: One method to handle all the struct types that embed one common struct (json marshalling)

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

报告相同问题?

悬赏问题

  • ¥15 nginx中的CORS策略应该如何配置
  • ¥30 信号与系统实验:采样定理分析
  • ¥100 我想找人帮我写Python 的股票分析代码,有意请加mathtao
  • ¥20 Vite 打包的 Vue3 组件库,图标无法显示
  • ¥15 php 同步电商平台多个店铺增量订单和订单状态
  • ¥15 关于logstash转发日志时发生的部分内容丢失问题
  • ¥17 pro*C预编译“闪回查询”报错SCN不能识别
  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题