Golang有2种切片类型和1个字段



考虑到golang不支持联合,实现的最佳方法是:

type foo struct {
    words []string
    nums []int
}

使得一次只能使用wordsnums。我试过的一件事是:

type foo struct {
    values []interface{}
}

但是我更喜欢将类型限制为前面提到的两种或者带有指针的东西

使用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
}

另一个选择是使用接口和类型断言。

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 playground示例:GoPlay

注意:

  1. Foo不能是接口类型(类型Foo []interface{}或类型Foo interface{}),但可以是包含接口类型的结构体。

  2. 您也不能将[]interface{}断言为另一个片类型,因为[]interface{}本身就是一个类型。看到

最新更新