可以将先前声明的函数绑定到结构体吗?

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

Is it possible to bind a previously declared function to a struct?

问题

在Go语言中,一个函数可以绑定到多个结构体吗?例如:

package main

import "fmt"

// 非常有用的函数,A和B都需要它
func SayHi() {
    fmt.Println("hi!")
}

type A struct{} // A需要SayHi :(

type B struct{} // B需要SayHi :(

func main() {
    a := A{}
    a.SayHi()
    b := B{}
    b.SayHi()
}

主要原因是我不想为每个需要它的类型重复实现SayHi函数,所以以下方式不能满足要求:

type A struct {}

func A SayHi() {
    fmt.Println("hi!")
}

type B struct {}

func B SayHi() {
    fmt.Println("hi!")
}

换句话说,如何在结构体之间共享、继承或绑定方法?

PS:不确定Go语言对此使用什么术语,但似乎接口在这种情况下不适用,因为它要求每个结构体重新实现方法。

英文:

Is it possible to bind a previously declared function to more than one struct? Ex:

package main

import "fmt"

// very useful function both A and B should have
func SayHi() {
    fmt.Println("hi!")
}

type A struct {} // A needs SayHi :(

type B struct {} // B needs SayHi :(

func main() {
     a := A{}
     a.SayHi()
     b := B{}
     b.SayHi()
}

The main reason is that I don't want to repeat SayHi implementation for each type that needs it, so this won't fulfill as an answer:

type A struct {}

func A SayHi() {
    fmt.Println("hi!")
}

type B struct {}

func B SayHi() {
    fmt.Println("hi!")
}

In other words, how to borrow|inherit|share|bind methods between structs?

PS: Not sure what terminology Go uses for that, but it seems interfaces doesn't apply to this case since it would require methods to be re implemented for each struct.

答案1

得分: 3

一种方法是将该方法声明为第三个结构体的一部分:

type Foo struct {}

func (f Foo) SayHi() {
    fmt.Prinln("hi!")
}

然后通过嵌入将此方法添加到A中:

type A struct {
    Foo
}

A将公开Foo的所有方法,并且由于Foo是一个空结构体,它不会影响其内存布局。请注意,当调用SayHi方法时,它不知道它是在A还是Foo变量上调用的,因此这只适用于自包含方法。

如果方法体确实需要知道接收器的类型,则需要在A上显式声明该方法。您可以将方法体提取到一个辅助函数中,以与其他类型共享实现。

英文:

One way to do this is to declare the method as part of a third struct:

type Foo struct {}

func (f Foo) SayHi() {
    fmt.Prinln("hi!")
}

This method can then be added to A by embedding it:

type A struct {
    Foo
}

A will expose all the methods of Foo, and since Foo is an empty struct it doesn't affect its in-memory layout. Note that when the SayHi method is called, it won't know whether it is being called on an A or Foo variable, so this is only really appropriate for self contained methods.

If the method body does need to know the type of the receiver, you will need to explicitly declare the method on A. You could factor out the body into a helper function to share the implementation with other types.

huangapple
  • 本文由 发表于 2014年12月20日 13:12:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/27577167.html
匿名

发表评论

匿名网友

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

确定