在创建结构体时正确使用接口。

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

Using interfaces correctly when creating structs

问题

我正在尝试编写一个小程序,其中包含几个包,每个包都有一个实现接口的结构体。我的想法是根据用户输入,我可以选择使用哪个包来构建特定的结构体,然后调用它们都应该具有的函数。由于我事先不知道类型,我以为可以使用interface{}并将其用作前向声明(请参见最后的代码片段)。我有一个类似这样的东西:

foo包中,我有以下内容:

package foo

type FooInput struct {
    Bar string
    Baz int
}

type Foo interface {
    Ding()
    Dong()
}

在另一个包bob中,我有以下内容:

package bob

import "your-package/foo"

type Bob struct {
    foo.FooInput
}

func (mybob *Bob) Ding() {}
func (mybob *Bob) Dong() {}

func MakeBob(foo_input foo.FooInput) (*Bob, error) {
    my_bob := Bob{foo_input}
    return &my_bob, nil
}

在我的主包中,我有以下内容:

package main

import (
    "your-package/foo"
    "your-package/bob"
)

func main() {
    foo_input := foo.FooInput{Bar: "awyiss", Baz: 1}
    var something foo.Foo
    var err error

    some_string := "foo"

    switch some_string {
    case "foo":
        something, err = bob.MakeBob(foo_input)
    case "bar":
        // imagine bar is like foo
        // something, err = bar.MakeBar(foo_input)
    // imagine other cases
    }

    something.Dong()
}

当运行/构建等操作时,我收到以下错误:

something.Dong undefined (type interface {} is interface with no methods)

我有点困惑我做错了什么...关于如何使用interface{}(如果需要的话)的任何解释都将非常有帮助!

英文:

I'm trying to write a small program in which I have a few packages, each with a struct that implements an interface. The idea is that based on user input, I can choose what package to use to build a particular struct and then call a function on it that they're all supposed to have. Since I don't know the type ahead of time, I was under the impression that I could use a interface{} and use that as a forward declaration (see the last code snippet). I have something that looks like this:

package foo

type FooInput struct {
	Bar string
	Baz    int
}

type Foo interface {
	Ding()
	Dong()
}

In another package, bob, I have something like:

type Bob struct {
    foo.FooInput
}
func (mybob *Bob) Ding() {}
func (mybob *Bob) Dong() {}
func MakeBob(foo_input foo.FooInput) (*Bob, error) {
    my_bob := Bob{foo_input}
    return &my_bob, nil
}

In my main package, I have something that looks like so:

data = foo.FooInput("awyiss", 1}
var something interface{}
var err error

switch some_string {
case "foo":
    something, err = bob.MakeBob(foo_input)
case "bar":
    // imagine bar is like foo
    something, err = bar.MakeBar(foo_input)
// imagine other cases
}
something.Dong()

When running / building / etc, I get the following error:

something.Dong undefined (type interface {} is interface with no methods)

I'm a bit confused as to what I'm doing wrong... any clarifiers on how I should use interface{} (if at all) would be extremely helpful!

答案1

得分: 1

变量 something 被声明为空接口。空接口上没有任何方法。要调用 Dong 方法,请将 something 声明为 foo.Foo

将代码中的

var something interface{}

改为

var something foo.Foo

这假设 bar 类似于 foo,意味着 bar 满足 foo.Foo 接口的要求。

英文:

The variable something is declared as the empty interface. There are no methods on the empty interface. To call the Dong method, declare something as a foo.Foo .

Change

var something interface{}

to

var something foo.Foo 

This assumes that bar being like foo means that bar satisfies the foo.Foo interface.

答案2

得分: 1

如果看起来你有点困惑,请选择两种可能性之一。如果你想将所有要放入变量"something"的类型都具有Ding和Dong方法,那么请为其定义接口。
Foo不是最好的名称,最好使用DingDonger(https://golang.org/doc/effective_go.html#interface-names)。

之后:

var something DingDonger

对于每个分配给something的值,都会检查类型是否真的具有所需的方法,因此something.Ding()不会引发错误。

如果任何变量的类型是interface{},则无法确定它是否具有该方法,你必须使用类型断言(https://golang.org/doc/effective_go.html#interface_conversions)来验证方法是否被实现。

英文:

If looks, that you are a bit confused. Please, choose - one of two possibilities. If all the types, that you want to put into variable "something" has methods Ding, and Dong - than define interface for it.
Foo is not the best name, better is DingDonger (https://golang.org/doc/effective_go.html#interface-names).

After:

var something DingDonger

each assign to something will be checked, whether type really has required methods, and therefore something.Ding() can not cause an error.

If any variable is type interface{} no one knows, whether it has or not such method and you have to use type assertion (https://golang.org/doc/effective_go.html#interface_conversions) to verify whether method is implemented.

huangapple
  • 本文由 发表于 2016年10月21日 12:02:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/40168185.html
匿名

发表评论

匿名网友

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

确定