接口实现中的非接口方法 [英] Non-interface methods in interface implementation

查看:92
本文介绍了接口实现中的非接口方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个定义方法的接口.我有一个实现这个接口的结构.在其中,我实现了该接口中的方法,并且还定义了其他方法.

例如:

包主进口 (fmt")类型动物界面{制造吵闹声()}类型狗结构{颜色串}/* 接口实现 */func (d *Dog) MakeNoise() {fmt.Println("吠叫!")}/* 结束接口实现 */func (d *Dog) WagTail() {fmt.Println(d.color + " dog: Wag wag")}func NewDog(color string) Animal {返回 &Dog{color}}功能主(){狗 := NewDog("棕色")dog.MakeNoise()dog.WagTail()}

在操场上:https://play.golang.org/p/B1GgoNToNl_l

这里,WagTail() 不是 Animal 接口的一部分,而是属于 Dog 结构体.运行此代码会出现错误

<块引用>

dog.WagTail 未定义(动物类型没有 WagTail 字段或方法).

有没有一种方法可以让结构坚持接口并定义它自己的方法?

解决方案

错误描述了一切:

<块引用>

dog.WagTail 未定义(动物类型没有字段或方法 WagTail)

要实现一个接口,您应该实现其中定义的所有方法.

dog := NewDog("Brown")dog.MakeNoise()dog.WagTail()

现在 NewDog 返回包含 MakeNoise 方法但不包含 WagTail 的 Animal 接口.

管理您的需求的唯一方法是创建一个结构类型为 Dog 的变量,然后您可以调用任何以 Dog 作为接收者的方法.

d := &Dog{"Brown"}d.WagTail()

或者你可以从 NewDog 方法返回指向 Dog 结构的指针,就像你在评论中提到的代码中所做的那样:

func NewDog(color string) *Dog {返回 &Dog{color}}

但是如果方法没有在接口中定义,你就不能使用结构体作为方法接收器来实现它.

Golang 提供了一种方式:

<块引用>

您可以要求编译器检查类型 T 是否实现了通过尝试使用 T 的零值进行赋值或接口 I指向 T 的指针,视情况而定

类型 T 结构{}var _ I = T{}//验证 T 实现了 I.var _ I = (*T)(nil)//验证 *T 实现了 I.

如果 T(或 *T,相应地)没有实现 I,错误将在编译时被捕获.

<块引用>

如果您希望界面的用户明确声明他们实现它,您可以将具有描述性名称的方法添加到接口的方法集.例如:

type Fooer interface {富()实现Fooer()}

然后一个类型必须实现ImplementsFooer方法才能成为Fooer,清楚地记录事实并在godoc的输出中宣布它.

类型栏结构{}func (b Bar) 实现Fooer() {}func (b Bar) Foo() {}

<块引用>

大多数代码没有使用这样的约束,因为它们限制了界面理念的实用性.但有时,它们是必要的解决相似接口之间的歧义.

I have an interface which defines a method. I have a struct which implements this interface. In it, I have implemented the methods from this interface and also have additional methods defined.

For example:

package main

import (
    "fmt"
)   

type Animal interface {
    MakeNoise()
}

type Dog struct {
    color string
}

/* Interface implementation */

func (d *Dog) MakeNoise() {
    fmt.Println("Bark!")
}

/* End Interface implementation */

func (d *Dog) WagTail() {
    fmt.Println(d.color + " dog: Wag wag")
}

func NewDog(color string) Animal {
    return &Dog{color}
}

func main() {
    dog := NewDog("Brown")
    dog.MakeNoise()
    dog.WagTail()

}

On Playground: https://play.golang.org/p/B1GgoNToNl_l

Here, WagTail() is not part of the Animal interface but belongs to the Dog struct. Running this code gives an error

dog.WagTail undefined (type Animal has no field or method WagTail).

Is there a way I could have a struct adhere to an interface and also define it's own methods?

解决方案

The error described it all:

dog.WagTail undefined (type Animal has no field or method WagTail)

To implement an interface you should implement all methods defined inside it.

dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()

Now NewDog returns Animal interface which contains MakeNoise method but not WagTail.

The only way to manage your requirement is either create a variable of struct type Dog and then you can call any method having Dog as receiver.

d := &Dog{"Brown"}
d.WagTail()

Or you can return the pointer to Dog struct from NewDog method just like you did in your code mentioned in the comment as:

func NewDog(color string) *Dog {
    return &Dog{color}
}

But if the method is not defined in interface you cannot implement it using the struct as method receiver.

Golang provides a way in which:

You can ask the compiler to check that the type T implements the interface I by attempting an assignment using the zero value for T or pointer to T, as appropriate

type T struct{}
var _ I = T{}       // Verify that T implements I.
var _ I = (*T)(nil) // Verify that *T implements I.

If T (or *T, accordingly) doesn't implement I, the mistake will be caught at compile time.

If you wish the users of an interface to explicitly declare that they implement it, you can add a method with a descriptive name to the interface's method set. For example:

type Fooer interface {
    Foo()
    ImplementsFooer()
}

A type must then implement the ImplementsFooer method to be a Fooer, clearly documenting the fact and announcing it in godoc's output.

type Bar struct{}
func (b Bar) ImplementsFooer() {}
func (b Bar) Foo() {}

Most code doesn't make use of such constraints, since they limit the utility of the interface idea. Sometimes, though, they're necessary to resolve ambiguities among similar interfaces.

这篇关于接口实现中的非接口方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆