在一个接口中通过其他方法实现一个方法,这种做法是否可行?

huangapple go评论80阅读模式
英文:

Is it possible to implement a method in one interface by others method in this interface?

问题

例如,一个名为Computable的接口,它有两个方法:Sqrt()Abs()

如果我想要添加一个名为Curve()的方法来计算sqrt和abs的和。

type Computable interface { 
    Sqrt() number  // 方法1
    Abs() number   // 方法2
    Curve() number // 方法应该调用Sqrt() + Abs()
}

显然,不需要为所有接口实现重新编写第三个方法。在C++/Java中,解决这个问题非常容易。但是谁能告诉我如何实现它?

英文:

For example, an interface named Computable, which has two methods: Sqrt() and Abs().

If I want to add a method named Curve() to compute the sum of sqrt and abs.

type Computable interace { 
    Sqrt() number  // method 1
    Abs() number   // method 2
    Curve() number // method should call Sqrt() + Abs()
}

Obvoiously, no need to rewrite the third method for all interface implementation. In C++/Java, it is very easy to resovle it.But who can tell how to implement it?

答案1

得分: 7

在Go语言中,接口中没有默认方法实现。

在你的情况下,最简单的解决方案是将Curve()移出接口,并将其实现为一个简单的函数:

type Computable interface {
    Sqrt() number // 方法1
    Abs() number  // 方法2
}

func Curve(c Computable) number {
    return c.Sqrt() + c.Abs()
}

如果必须将其作为接口的一部分,那么你可以创建一个单独的Curve()实现,它使用Computable的值作为其"源":

type curveImpl struct {
    Computable
}

func (c curveImpl) Curve() number {
    return c.Sqrt() + c.Abs()
}

希望实现Computable的具体类型可以嵌入curveImpl,但为了使其工作,必须正确初始化:

type Foo struct {
    curveImpl
}

func (Foo) Sqrt() number { return 2.0 }
func (Foo) Abs() number  { return 4.0 }

func main() {
    f := Foo{}
    f.curveImpl = curveImpl{f}

    fmt.Println(f.Curve())
}

上面的示例输出为6(在Go Playground上尝试一下)。

可以看到,这样做会有一些麻烦。因此,在这种情况下,是否值得这样做是值得商榷的。如果Curve()很简单,我宁愿在需要的地方直接实现它。如果Curve()要复杂得多,那么也许这种权衡是值得的。

再次强调:在这里,最简单的方法是使用Curve()函数而不是Curve()方法。

英文:

There are no default method implementations in Go.

The easiest solution in your case would be to move Curve() outside of the interface, and implement it as a simple function:

type Computable interface {
	Sqrt() number // method 1
	Abs() number  // method 2
}

func Curve(c Computable) number {
	return c.Sqrt() + c.Abs()
}

If it must be part of the interface, then you may create a single implementation of Curve() that uses a value of Computable as its "source":

type curveImpl struct {
	Computable
}

func (c curveImpl) Curve() number {
	return c.Sqrt() + c.Abs()
}

Concrete types that wish to implement Computable may embed curveImpl, but for it to work, it must be initialized properly:

type Foo struct {
	curveImpl
}

func (Foo) Sqrt() number { return 2.0 }
func (Foo) Abs() number  { return 4.0 }

func main() {
	f := Foo{}
	f.curveImpl = curveImpl{f}

	fmt.Println(f.Curve())
}

The above example outputs 6 (try it on the Go Playground).

As you can see there is some hassle involved making this work. So in this case it's questionable whether it's worth it. If Curve() is this simple, I would just rather implement it where needed. If Curve() would be a lot more complex, then maybe the trade-off is worth it.

Again: easiest would be to use a Curve() function instead of a method here.

huangapple
  • 本文由 发表于 2021年9月2日 19:56:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/69029807.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定