Function Go中的泛型编程?

Function Go中的泛型编程?,function,templates,go,overloading,generic-programming,Function,Templates,Go,Overloading,Generic Programming,我知道Go不支持模板或重载函数,但我想知道是否有任何方法可以进行某种泛型编程 我有许多功能,例如: func (this Document) GetString(name string, default...string) string { v, ok := this.GetValueFromDb(name) if !ok { if len(default) >= 1 { return default[0] } els

我知道Go不支持模板或重载函数,但我想知道是否有任何方法可以进行某种泛型编程

我有许多功能,例如:

func (this Document) GetString(name string, default...string) string {
    v, ok := this.GetValueFromDb(name)
    if !ok {
        if len(default) >= 1 {
            return default[0]
        } else {
            return ""
        }
    }
    return v.asString
}

func (this Document) GetInt(name string, default...int) int {
    v, ok := this.GetValueFromDb(name)
    if !ok {
        if len(default) >= 1 {
            return default[0]
        } else {
            return 0
        }
    }
    return v.asInt
}

// etc. for many different types

有没有办法在没有这么多冗余代码的情况下做到这一点?

您可以实现的最大功能是使用
接口{}
类型,如下所示:

func (this Document) Get(name string, default... interface{}) interface{} {
    v, ok := this.GetValueFromDb(name)
    if !ok {
        if len(default) >= 1 {
            return default[0]
        } else {
            return 0
        }
    }
    return v
}
GetValueFromDb
函数也应该调整为返回
interface{}
值,而不是像现在这样的包装器

然后在客户端代码中,您可以执行以下操作:

value := document.Get("index", 1).(int)  // Panics when the value is not int

但这将产生一些运行时开销。我最好坚持使用单独的函数,并尝试以某种方式重新构造代码。

以下是如何更改代码的示例

因为您知道给定名称的类型,所以可以以通用方式编写Get方法,返回
接口{}
,然后在调用站点断言该类型。请参阅有关的规范


在Go中有不同的方法来模拟泛型的某些方面。邮件列表上有很多讨论。通常,有一种方法可以重组代码,从而减少对泛型的依赖

在客户端代码中,您可以这样做:

res := GetValue("name", 1, 2, 3)
// or
// res := GetValue("name", "one", "two", "three")

if value, ok := res.(int); ok {
    // process int return value
} else if value, ok := res.(string); ok {
    // process string return value
}

// or
// res.(type) expression only work in switch statement
// and 'res' variable's type have to be interface type
switch value := res.(type) {
case int:
    // process int return value
case string:
    // process string return value
}

我同时发布了同样的建议:-)
res := GetValue("name", 1, 2, 3)
// or
// res := GetValue("name", "one", "two", "three")

if value, ok := res.(int); ok {
    // process int return value
} else if value, ok := res.(string); ok {
    // process string return value
}

// or
// res.(type) expression only work in switch statement
// and 'res' variable's type have to be interface type
switch value := res.(type) {
case int:
    // process int return value
case string:
    // process string return value
}