【发布时间】:2013-01-29 22:29:12
【问题描述】:
给定一个接口和两个(或更多)实现,我很难在扩展功能时轻松切换实现。
例如假设有接口 INumber 支持 Inc 和 String 以及两个实现 NumberInt32 和 NumberInt64 以及它们的明显实现。假设我想在 INumber 之上实现一个 EvenCounter。 EvenCounter 只有一个 IncTwice 并且应该调用 Inc 两次。我很难在不使用 EvenCounter 中 INumber 周围的额外结构的情况下获得正确的类型。
type INumber interface {
Inc()
String() string
}
type NumberInt32 struct {
number int32
}
func NewNumberInt32() INumber {
ret := new(NumberInt32)
ret.number = 0
return ret
}
func (this *NumberInt32) Inc() {
this.number += 1
}
func (this *NumberInt32) String() string {
return fmt.Sprintf("%d", this.number)
}
// type NumberInt64.... // obvious
这是我挣扎的地方
type EvenCounter1 INumber // nope, additional methods not possible
type EvenCounter2 NumberInt32 // nope
func (this *EvenCounter2) IncTwice() {
for i:=0; i < 2; i+=1 {
// this.Inc() // Inc not found
// INumber(*this).Inc() // cannot convert
// in, ok := *this.(INumber) // cannot convert
// v, ok := this.(INumber) // cannot convert
// a concrete conversion a) does not work and b) won't help
// here it should be generic
// v, ok := this.(NumberInt32)
// How do I call Inc here on this?
}
}
只需嵌入到结构中即可...
type EvenCounter3 struct {
n INumber
}
func (this *EvenCounter3) IncTwice() {
n := this.n // that is a step I want to avoid
n.Inc() // using this.n.Inc() twice makes it slower
n.Inc()
}
func (this *EvenCounter3) String() string {
return this.n.String()
}
我可以忍受为每种方法手动实现委托的需要,但是 显然我想依赖 INumber 而不是具体的实现(即 将意味着改变很多地方来尝试另一种实现,但是,我想避免额外的间接和(很可能?)额外的空间。有没有 避免结构并直接说 EvenCounter 是带有其他方法的(特定)INumber 的方法?
顺便说一句,真正的例子是一组整数和一个整数到整数的映射,数百万个实例都交织在一起(不,只是 map[int]bool 是不够的 - 太慢了,bitset 很有趣,取决于用例等)并通过更改代码中的 2-3 行轻松测试 set 和 map 的不同实现(理想情况下只是类型,也许 实例的通用创建。复制)
任何帮助表示赞赏,我希望这还没有被问到......
【问题讨论】:
标签: types interface go implementation