是否可以在Go中定义匿名接口实现?

时间:2019-01-10 11:59:25

标签: go interface

考虑一些给定的接口以及使用它的虚构库的功能

// Binary and Ternary operation on ints
type NumOp interface {
    Binary(int, int) int
    Ternary(int, int, int) int
}

func RandomNumOp(op NumOp) {
    var (
        a = rand.Intn(100) - 50
        b = rand.Intn(100) - 50
        c = rand.Intn(100) - 50
    )
    fmt.Printf("%d <op> %d = %d\n", a, b, op.Binary(a,b))
    fmt.Printf("%d <op> %d <op> %d = %d\n", a, b, c, op.Ternary(a,b,c))
}

实现该接口的可能类型可能是

// MyAdd defines additions on 2 or 3 int variables
type MyAdd struct {}
func (MyAdd) Binary(a, b int) int {return a + b }
func (MyAdd) Ternary(a, b, c int) int {return a + b + c }

我正在处理许多不同的接口,这些接口定义了一些函数,在某些情况下,这些函数需要使用大多数像NOP类操作的函数来实现,而不依赖于任何结构 member 并且仅在项目中的单个位置使用(无需重复使用)。

Go中是否有一种更简单(较不冗长)的方法来定义一个使用匿名函数的(最好)匿名实现接口,就像(伪代码,我知道那样行不通):

RandomNumOp({
   Binary: func(a,b int) int { return a+b},
   Ternary: func(a,b,c int) int {return a+b+c},
})

1 个答案:

答案 0 :(得分:5)

如果实施必须可行

如果实现该接口的值必须有效(例如,其方法必须可以调用而不会出现紧急情况),那么您将无法做到这一点。

方法声明必须在顶层(文件级)。并且要实现一个具有0个以上方法的接口,则需要在某个地方声明方法。

当然,您可以使用结构并嵌入现有的实现,但是再次,它需要已经有一个现有的实现,该实现的方法必须已经在文件级“某处”定义。

如果您需要“虚拟”但可行的实现,则可以使用/传递 any 实现,例如您的MyAdd类型的值。如果您想强调实现无关紧要,请创建一个虚拟实现,其名称表示:

type DummyOp struct{}

func (DummyOp) Binary(_, _ int) int     { return 0 }
func (DummyOp) Ternary(_, _, _ int) int { return 0 }

如果您需要动态提供方法的 some 的实现,则可以创建一个代表该方法功能的委托结构类型,然后实际方法检查是否已设置相应的功能。称为哪种情况,否则将无济于事。

它是这样的:

type CustomOp struct {
    binary  func(int, int) int
    ternary func(int, int, int) int
}

func (cop CustomOp) Binary(a, b int) int {
    if cop.binary != nil {
        return cop.binary(a, b)
    }
    return 0
}

func (cop CustomOp) Ternary(a, b, c int) int {
    if cop.ternary != nil {
        return cop.ternary(a, b, c)
    }
    return 0
}

使用它时,您可以自由地仅提供一部分功能,其余功能将变为无操作:

RandomNumOp(CustomOp{
    binary: func(a, b int) int { return a + b },
})

如果不需要执行工作

如果您只需要一个实现接口的值,而又不需要它的方法是“可调用的”(如果被调用,则不会慌张),您可以简单地使用一个匿名结构文字,嵌入接口类型:

var op NumOp = struct{ NumOp }{}