Go 有点;方法重载“;在围棋中?

Go 有点;方法重载“;在围棋中?,go,overloading,Go,Overloading,假设我得到一个名为State的类型: type State struct { // ... does not matter what is inside } 以及在其上定义的方法: func (s *State) prettyName() string { return "I am a state!" } 目前我无法改变prettyName()的行为。我知道,Go故意逃避OOP类继承和方法重载,这可能永远不会改变,但是:如果我需要prettyName()根据任何因素做出不同的

假设我得到一个名为
State
的类型:

type State struct {
    // ... does not matter what is inside
}
以及在其上定义的方法:

func (s *State) prettyName() string {
    return "I am a state!"
}
目前我无法改变
prettyName()
的行为。我知道,
Go
故意逃避OOP类继承和方法重载,这可能永远不会改变,但是:如果我需要
prettyName()
根据任何因素做出不同的行为,该怎么办?我看到的唯一解决方案是:

type State struct {
    _prettyName func() string
}
func (s *State) prettyName() string {
    return s._prettyName()
}

是否有更好的
Go
风格的方法来实现相同的目标

这里应该有一个接口

创建一个像

type Stateful interface  {
    State() string
}
和基态类型

type BaseState struct{
}
func (s BaseState) State() string{
    return "Base state"
} 
您可以嵌入
BaseState
struct

type MyStruct struct{
    BaseState
}
因此,
状态
将返回
“基本状态”
,但也可以实现自己的方法

func (s MyStruct) State() string{
    return "New State"
} 
现在
状态
将返回
“新状态”


这里应该有一个界面

创建一个像

type Stateful interface  {
    State() string
}
和基态类型

type BaseState struct{
}
func (s BaseState) State() string{
    return "Base state"
} 
您可以嵌入
BaseState
struct

type MyStruct struct{
    BaseState
}
因此,
状态
将返回
“基本状态”
,但也可以实现自己的方法

func (s MyStruct) State() string{
    return "New State"
} 
现在
状态
将返回
“新状态”


您也可以定义函数类型的成员值,而不是将
prettyName
作为
struct
上的方法

type State struct {
    prettyName func() string
}
然后可以在运行时将其值设置为任何函数

a := State{}
a.prettyName = func() string {
    return "I am a state!"
}
fmt.Println(a.prettyName())
a.prettyName = func() string {
    return "another state"
}
fmt.Println(a.prettyName())
这个例子正在进行中

现在,您可以使用
PrettyName
API定义接口类型,进一步的算法/业务逻辑将调用
PrettyName

type StateAPI interface {
    PrettyName () string
}
要将
State
类型放入
StateAPI
界面,需要在私有函数成员周围定义一个简单的
PrettyName
方法

func (s *State) PrettyName() string {
    return s.prettyName()
}
这基本上是你最初的想法,完全合法。中有一个例子正好使用此构造。 该示例按不同字段对音乐记录进行排序,例如,按年份、按艺术家等,以便使用API

输入数据需要有三种方法

type Interface interface {
        // Len is the number of elements in the collection.
        Len() int
        // Less reports whether the element with
        // index i should sort before the element with index j.
        Less(i, j int) bool
        // Swap swaps the elements with indexes i and j.
        Swap(i, j int)
}
按不同字段排序的一种方法是为每个案例定义一种自定义数据类型,例如
ByYear
ByArtist
,等等,并为每个案例定义所有三种API方法。但是
Len
Swap
方法对于所有情况都是多余的。更好的解决方案是只使用函数成员定义一种自定义数据类型

//!+customcode
type customSort struct {
    t    []*Track
    less func(x, y *Track) bool
}
func (x customSort) Less(i, j int) bool { 
     return x.less(x.t[i], x.t[j]) }
func (x customSort) Len() int           {
     return len(x.t) }
func (x customSort) Swap(i, j int)      {
     x.t[i], x.t[j] = x.t[j], x.t[i] }
然后您可以通过编程控制
less
的含义


源代码是而不是
struct
上的
prettyName
作为方法,您还可以定义函数类型的成员值

type State struct {
    prettyName func() string
}
然后可以在运行时将其值设置为任何函数

a := State{}
a.prettyName = func() string {
    return "I am a state!"
}
fmt.Println(a.prettyName())
a.prettyName = func() string {
    return "another state"
}
fmt.Println(a.prettyName())
这个例子正在进行中

现在,您可以使用
PrettyName
API定义接口类型,进一步的算法/业务逻辑将调用
PrettyName

type StateAPI interface {
    PrettyName () string
}
要将
State
类型放入
StateAPI
界面,需要在私有函数成员周围定义一个简单的
PrettyName
方法

func (s *State) PrettyName() string {
    return s.prettyName()
}
这基本上是你最初的想法,完全合法。中有一个例子正好使用此构造。 该示例按不同字段对音乐记录进行排序,例如,按年份、按艺术家等,以便使用API

输入数据需要有三种方法

type Interface interface {
        // Len is the number of elements in the collection.
        Len() int
        // Less reports whether the element with
        // index i should sort before the element with index j.
        Less(i, j int) bool
        // Swap swaps the elements with indexes i and j.
        Swap(i, j int)
}
按不同字段排序的一种方法是为每个案例定义一种自定义数据类型,例如
ByYear
ByArtist
,等等,并为每个案例定义所有三种API方法。但是
Len
Swap
方法对于所有情况都是多余的。更好的解决方案是只使用函数成员定义一种自定义数据类型

//!+customcode
type customSort struct {
    t    []*Track
    less func(x, y *Track) bool
}
func (x customSort) Less(i, j int) bool { 
     return x.less(x.t[i], x.t[j]) }
func (x customSort) Len() int           {
     return len(x.t) }
func (x customSort) Swap(i, j int)      {
     x.t[i], x.t[j] = x.t[j], x.t[i] }
然后您可以通过编程控制
less
的含义


源代码是

您考虑过接口吗?@mkopriva,您的意思是,有许多
状态行为
状态行为
,…-所有驱动相同的
IState
接口的方法,在
Go
的情况下,仅公开相同签名和名称的相同数量的方法?正确,但如果您只想对一个方法执行此“重载”,则可以将接口嵌入状态,然后根据“任意因素”设置实现@mkopriva,每个行为不需要一个命名的instace吗?另外,我这样做的方式允许动态构建对象-不需要命名实例,但我可以将其他代码绑定到
IState
接口。您考虑过接口吗?@mkopriva,您的意思是,有许多
statebehavior
statebehavior
,…-所有驱动相同的
IState
接口的方法,在
Go
的情况下,仅公开相同签名和名称的相同数量的方法?正确,但如果您只想对一个方法执行此“重载”,则可以将接口嵌入状态,然后根据“任意因素”设置实现@mkopriva,每个行为不需要一个命名的instace吗?另外,我这样做的方式允许动态构建对象-不需要命名实例,但我可以将其他代码绑定到
IState
接口。