我正在努力学习Go。
我在go gopkg.in/fatih/set.v0中找到了这个巧妙的Set实现,但是我更喜欢用set.Set
更明确的名称来命名我的集合,做类似的事情:
type View set.Set
本质上,我希望我的View
类型继承set.Set
的方法。因为,View
是描述符的 set.Set
。但我知道Go在继承方面非常高峰,而且输入一般。
目前我一直在尝试以下 kinda 继承,但在尝试使用func Union(set1, set2 Interface, sets ...Interface) Interface
或func (s *Set) Merge(t Interface)
等函数时会导致大量错误:
type View struct {
set.Set
}
我想知道是否有办法以类似Go的方式实现我想要的东西,或者我只是想将我的优秀'OO实践应用于丢弃它们的语言,请。
答案 0 :(得分:18)
答案 1 :(得分:1)
注意,我认为你最初提出的简单别名在语法上是有效的,虽然快速查看了集合库,而不是别名set.Set
它可能对别名set.Interface
更有意义,例如:
package main
import (
"fmt"
set "gopkg.in/fatih/set.v0"
)
// View is a type alias for the set.Interface interface
type View set.Interface
// Display takes one of our View types in order to print it.
func Display(view View) {
fmt.Println(view.List())
}
func main() {
// create our first set.Interface or View
v1 := set.New()
v1.Add("foo")
// create our second set.Interface or View
v2 := set.New("bar")
// call a set function
v3 := set.Union(v1, v2)
// call our function that takes a View
Display(v3)
}
你可能已经注意到我在某种程度上作弊,因为我没有真正提到上面代码中的别名类型,除了定义Display
函数的参数之外,你将在其中注意到View
函数{1}}实例而不是set.Interface
。如果你有很多功能处理这些事情,那么你的域名可能会更具表现力。
请注意,因为我们的View
类型是接口类型的别名,所以它排除了将自己的函数添加到该类型,因为Go不允许我们为函数设置接口接收器类型(我可能是表达错误)。我的意思是你不能做任何事情:
func (v View) Display() string {
return v.String()
}
总之,我认为别名是好的,它可以使内部API更具可读性,并且您可以依靠编译器来帮助消除某些类型的错误;但是,这不允许您向自定义类型添加功能。如果需要,则需要采用替代方法,即嵌入或简单合成(即View
具有Set
)。