鉴于golang不支持工会这一事实,最佳实现方式是什么:
type foo struct {
words []string
nums []int
}
这样只能同时使用words
或nums
。我尝试过的一件事是:
type foo struct {
values []interface{}
}
但是我更喜欢将类型限制为提到的两个或带指针的东西。
答案 0 :(得分:3)
使用foo
包隐藏实施。例如,
package foo
const (
typeWords = iota + 1
typeNums
)
type Foo struct {
fooType byte
words []string
nums []int
}
func NewWords(words []string) *Foo {
return &Foo{fooType: typeWords, words: words}
}
func NewNums(nums []int) *Foo {
return &Foo{fooType: typeNums, nums: nums}
}
func (f *Foo) Words() []string {
if f.fooType != typeWords {
return nil
}
return f.words
}
func (f *Foo) Nums() []int {
if f.fooType != typeNums {
return nil
}
return f.nums
}
附录:
由于我们隐藏了包foo
的实现,我们可以用另一种方式实现它。例如,我们可以采用twinj的建议并使用界面。为了确保某种程度的一般性,让我们添加另一个[]string
类型Phrases
。值类型用于区分两种[]string
类型。
package foo
type (
valueWords []string
valuePhrases []string
valueNums []int
)
type Foo struct {
value interface{}
}
func NewWords(words []string) *Foo {
return &Foo{value: valueWords(words)}
}
func (f *Foo) Words() []string {
value, ok := f.value.(valueWords)
if !ok {
return nil
}
return value
}
func NewPhrases(phrases []string) *Foo {
return &Foo{value: valuePhrases(phrases)}
}
func (f *Foo) Phrases() []string {
value, ok := f.value.(valuePhrases)
if !ok {
return nil
}
return value
}
func NewNums(nums []int) *Foo {
return &Foo{value: valueNums(nums)}
}
func (f *Foo) Nums() []int {
value, ok := f.value.(valueNums)
if !ok {
return nil
}
return value
}
答案 1 :(得分:3)
另一种选择是使用接口并输入断言。
type Foo struct {
values interface{}
}
func (o *Foo) Words() []string {
if v, ok := o.values.([]string); ok {
return v
}
return nil
}
func (o *Foo) Nums() []int {
if v, ok := o.values.([]int); ok {
return v
}
return nil
}
查看Go游乐场示例:GoPlay
注意:
Foo不能是接口类型(类型为Foo [] interface {}或类型为Foo接口{}),但可以是包含接口类型的结构。
您也无法将[] interface {}断言为另一个切片类型,因为[] interface {}本身就是一种类型。 See here