【发布时间】:2015-08-31 03:38:21
【问题描述】:
我目前的问题是我正在实现数据结构并且我已经为它们编写了迭代器。我的数据结构、迭代器和所有其他必需对象都有可见的接口。在后面我有具体的实现,我希望对最终用户隐藏。
这需要我的许多函数返回 interface{} 对象,以便我可以存储任何类型的对象(并将验证留给最终用户)。
我遇到的一个问题是我迭代了一个图表。我的图实现的迭代器{}返回一个具体的顶点类型,但迭代器接口返回接口{}。由于最终用户只能使用我的基本 Vertex 接口,因此我必须尝试转换为 Vertex 接口以便他们可以使用它。
这是我此时能想到的最小示例,它说明了我的问题:
package main
import (
"fmt"
"strconv"
)
type Base interface {
Required() string
}
type Concrete struct {
_data int
}
func (con *Concrete) Required() string {
return strconv.Itoa(con._data)
}
func convert(val interface{}) *Base {
if con,ok := val.(*Base); ok {
return con
}
return nil
}
func main() {
conc := new(Concrete)
conc._data = 5
base := convert(conc)
fmt.Println(base)
}
在上面的代码中,我真的希望 convert 将类型转换为 *Base。函数 convert 将返回值 nil 而不是我希望的可爱值。
编辑:删除了未使用的代码,我以为我已经删除了它,但我想没有。
【问题讨论】:
-
如果您查看specification of type assertions,您会发现您的
convert函数只是base, _ := conc.(Base)。它将根据需要返回零值(指针为 nil)。但是,很少需要忽略布尔值。如果您的代码期望它是唯一添加元素的东西,那么使用base := conc.(Base)是合适的。您希望运行时在检测到代码中的错误时发生恐慌,就像切片/数组边界检查失败一样会恐慌。 -
@DaveC 我有一个方法的原因是因为我在几个地方调用它。如果我更改基础类型,我不想在一堆地方更改它。我离开布尔检查的唯一原因是因为我喜欢它的外观。