我知道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有没有办法在没有这么多冗余代码的情况下做到这一点呢?
发布于 2013-02-27 17:06:07
你能做的最多的就是使用interface{}类型,如下所示:
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或
value, ok := document.Get("index", 1).(int) // ok is false if the value is not int不过,这会产生一些运行时开销。我最好坚持使用独立的函数,并尝试以某种方式重新构造代码。
发布于 2013-02-27 17:11:14
这是一个关于如何更改代码的working example。
由于您知道给定名称所需的类型,因此可以以泛型方式编写Get方法,返回interface{},然后在调用点断言该类型。请参阅有关type assertions的规范。
在Go中有不同的方式来模拟泛型的某些方面。在邮件列表上有很多讨论。通常,有一种方法可以重构代码,从而减少对泛型的依赖。
发布于 2014-12-04 11:32:26
在客户端代码中,您可以这样做:
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
}https://stackoverflow.com/questions/15104795
复制相似问题