Go 中的通用编程?
Posted
技术标签:
【中文标题】Go 中的通用编程?【英文标题】:Generic programming in Go? 【发布时间】:2013-02-27 05:24:51 【问题描述】:我知道 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
有没有什么方法可以做到这一点而无需太多冗余代码?
【问题讨论】:
【参考方案1】:您可以实现的大部分是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
但这会产生一些运行时开销。我最好坚持使用单独的函数并尝试以某种方式重组代码。
【讨论】:
【参考方案2】:这里是working example,说明如何更改代码。
由于您知道给定名称的期望类型,您可以以通用方式编写 Get 方法,返回 interface
,然后在调用站点断言类型。请参阅有关 type assertions 的规范。
在 Go 中模拟泛型的某些方面有不同的方法。邮件列表上有很多讨论。通常,有一种方法可以重组代码,从而减少对泛型的依赖。
【讨论】:
【参考方案3】:在客户端代码中你可以这样做:
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
【讨论】:
以上是关于Go 中的通用编程?的主要内容,如果未能解决你的问题,请参考以下文章