如何在Go中将相同的方法应用于不同的类型?

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

How to apply same method to different types in Go?

问题

如何在Go语言中避免重复代码,将相同的方法应用于不同的类型?我有type1和type2两种类型,并且想要应用Do()方法。

type type1 struct { }
type type2 struct { }

我不得不重复代码,如下所示。Go语言是静态类型的,所以类型必须在编译时确定。

func (p type1) Do() { }
func (p type2) Do() { }

这样做是可以的,但我不喜欢重复代码。

type1.Do()
type2.Do()

你可以使用接口来避免重复代码。首先,定义一个包含Do()方法的接口:

type Doer interface {
    Do()
}

然后,让type1和type2实现这个接口:

func (p type1) Do() { }
func (p type2) Do() { }

现在,你可以使用接口类型来调用Do()方法,而不需要重复代码:

var t1 type1
var t2 type2

var doer Doer

doer = t1
doer.Do()

doer = t2
doer.Do()

通过使用接口,你可以将相同的方法应用于不同的类型,而不需要重复代码。

英文:

How to apply same method to different types without repeating code in Go ? I have type1 and type2 and want to apply method Do()

type type1 struct {  }
type type2 struct {  }

I have to repeat code , see below. Go has static typing, so type has to be determined during compile time.

func (p type1) Do() {   }
func (p type2) Do() {   }

This works fine ..but I don't like repeating code

type1.Do()
type2.Do()

答案1

得分: 4

这里的逻辑不太清楚,但在Go语言中有一种常见的模式,即将共享功能封装在另一个结构体类型中,然后将其嵌入到你的类型中:

type sharedFunctionality struct{}

func (*sharedFunctionality) Do() {}

type type1 struct{ sharedFunctionality }
type type2 struct{ sharedFunctionality }

现在你可以在type1type2实例上调用Do()方法,或者在任何需要这个功能的其他类型上调用。

**编辑:**根据你的评论,你可以重新定义一些等效的类型,比如t1t2,以符合所需的协议(具有Do()方法),如下所示:

func main() {
    var j job

    j = new(t1)
    j.Do()

    j = new(t2)
    j.Do()
}

type job interface {
    Do()
}

type t1 another.Type1

func (*t1) Do() {}

type t2 yetanother.Type2

func (*t2) Do() {}

这里的类型another.Type1yetanother.Type2并非由你定义。但你可以根据逻辑要求对t1t2进行任何操作 - 只要涉及公共成员,或者如果你愿意使用反射的话 如何在Go中将相同的方法应用于不同的类型?

英文:

It's not clear how the logic goes here, but one common pattern in Go is encapsulating the shared functionality in another struct type and then embed it in your type:

type sharedFunctionality struct{}

func (*sharedFunctionality) Do() {}

type type1 struct{ sharedFunctionality }
type type2 struct{ sharedFunctionality }

Now you can call Do() on type1 and type2 instances or in any other type that you need this functionality.

Edit: based on your comment, you can just redefine some equivalent types such as t1 and t2 that follow the desired protocol (having a Do() method) like this:

func main() {
	var j job

	j = new(t1)
	j.Do()

	j = new(t2)
	j.Do()
}

type job interface {
	Do()
}

type t1 another.Type1

func (*t1) Do() {}

type t2 yetanother.Type2

func (*t2) Do() {}

Here the types another.Type1 and yetanother.Type2 are not defined by you. But you can do whatever the logic demands with t1 and t2 - as far as public members go, or if you are willing to mess with that reflection thing 如何在Go中将相同的方法应用于不同的类型?

答案2

得分: 2

在Go语言中,最接近的方法是让一个类型嵌入另一个类型。

type Type1 struct {}

func (t *Type1) Do() {
   // ...
}

type Type2 struct {
    *Type1
}

这种方法的唯一限制是Do()函数只能访问Type1的字段。

英文:

The closest you can get in Go is to have one type embed another.

type Type1 struct {}

func (t *Type1) Do() {
   // ...
}

type Type2 struct {
    *Type1
}

The only limitation with this is that your Do() function will only have access to the fields of Type1.

答案3

得分: 1

我认为你可以在这里使用接口。示例:

package main

import "fmt"

type testInterface interface {
    Do()
}

type type1 struct{}
type type2 struct{}

func (t type1) Do() {
    fmt.Println("Do type 1")
}

func (t type2) Do() {
    fmt.Println("Do type 2")
}

func TestFunc(t testInterface) {
    t.Do()
}

func main() {
    var a type1
    var b type2

    TestFunc(a)
    TestFunc(b)
}
英文:

I think, you can use interface here. Example:

package main

import "fmt"

type testInterface interface {
	Do()
}

type type1 struct{}
type type2 struct{}

func (t type1) Do() {
	fmt.Println("Do type 1")
}

func (t type2) Do() {
	fmt.Println("Do type 2")
}

func TestFunc(t testInterface) {
	t.Do()
}

func main() {
	var a type1
	var b type2

	TestFunc(a)
	TestFunc(b)

}

huangapple
  • 本文由 发表于 2017年2月21日 03:34:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/42352873.html
匿名

发表评论

匿名网友

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

确定