考虑一些给定的接口以及使用它的虚构库的功能
// 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},
})
答案 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 }{}