Если реализация должна работать
Если значение, реализующее интерфейс, должно работать (например, его методы должны вызываться без паники), то вы не можете это сделать.
Объявления методов должны быть на верхнем уровне (уровень файла). И реализовать интерфейс с более чем 0 методами, для которых требуется где-то иметь объявления методов.
Конечно, вы можете использовать структуру и встраивать существующую реализацию, но опять же, она требует уже существующей реализации, методы которой уже должны быть определены «где-то»: на уровне файлов.
Если вам нужна «фиктивная», но работоспособная реализация, они используют / pass любую реализацию , например. значение вашего MyAdd
типа. Если вы хотите подчеркнуть, что реализация не имеет значения, то создайте фиктивную реализацию, имя которой означает, что:
type DummyOp struct{}
func (DummyOp) Binary(_, _ int) int { return 0 }
func (DummyOp) Ternary(_, _, _ int) int { return 0 }
Если вам нужно динамически предоставить реализацию для некоторых методов, вы можете создать тип структуры делегатора, который содержит функции для методов, и фактические методы проверяют, установлена ли соответствующая функция, в которой если это называется, иначе ничего не будет сделано.
Вот как это может выглядеть:
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 }{}