Golang 接口方法链接

Golang interface method chaining

我有一个接口 Cells 有几个方法

type Cells interface{
    Len() int
    //....
}

具体实现有StrCellsIntCellsFloatCellsBoolCells,都实现了上述方法。

例如:

type StrCells []string
func (sC StrCells) Len() int {return len(sC)}
//...

type IntCells []int
func (iC IntCells) Len() int {return len(iC)}
//...

//....

对于两个具体类型 - IntCellsFloatCells - 我想实现仅适用于这些类型的特定功能。

我创建了一个新界面 NumCells,其中嵌入了 Cells

type NumCells interface{
    Cells
    Add(NumCells) interface{} // should return either IntCells or FloatCells 
}

这是我对 IntCells 的 Add() 实现:

func (iC IntCells) Add(nC NumCells) interface{} {
    if iC.Len() != nC.Len() {
        // do stuff
    }
    switch nC.(type) {
    case IntCells:
        res := make(IntCells, iC.Len())
        for i, v := range iC {
            res[i] = v + nC.(IntCells)[i]
        }
        return res
    case FloatCells:
        res := make(FloatCells, iC.Len())
        for i, v := range iC {
            res[i] = float64(v) + nC.(FloatCells)[i]
        }
        return res
    default:
        // to come
        return nil
    }

}

这是我的问题/问题

该函数有效,但是,我实际上希望该函数为 return NumCells(即 IntCells 或 FloatCells),因此我可以像这样进行方法链接

a := columns.IntCells(1, 2, 4, 2)
b := columns.IntCells{2, 3, 5, 3}
c := columns.FloatCells{3.1, 2, 2.4, 3.2}
d := a.Add(b).Add(c)

如果 Add() return 是 interface{},这是不可能的。但是,我无法使该功能正常工作。

如果您以这种方式定义 NumCells 界面,它会起作用:

type NumCells interface{
    Cells
    Add(NumCells) NumCells // returns either IntCells or FloatCells
}

然后您需要 IntCellsFloatCells 来实现 Add 和 return 其中一种类型。

这是一个可用的 playground,使用方法链接并打印结果:

https://play.golang.org/p/W7DzcB4A3NH

如评论中所述,在使用接口时,人们通常希望使每种类型与其余实现无关,并且只使用不带类型开关的接口。

Add 的实现中避免这些类型切换的一种方法可能是在 NumCells 中添加另一种方法到 return 特定位置作为 float64 .

type NumCells interface{
    Cells
    Add(NumCells) NumCells // returns either IntCells or FloatCells
    GetCell(index int) float64
}

这样您就可以在不需要断言特定类型的情况下获取值。

由于IntCells不能容纳float64值,它仍然需要创建一个FloatCells到return它,如果我们想避免IntCells 这样做我们需要以某种方式抽象对象的创建,使用工厂模式或类似模式。