数据结构只允许一组? Golang

时间:2016-12-22 06:18:23

标签: go enums

什么是只允许一组可能选项的数据结构?

我尝试过使用enum,但它们不是我想要的。

package main

import "fmt"

type Event struct {
        day_number Day 
}

type Day int 

const (
        Monday Day = iota
        Tuesday
        Wednesday
        Thursday
        Friday
        Saturday
        Sunday
)

func main() {
        var r Event
        r.day_number = Monday
        fmt.Println(r.day_number)
        // Keep this from happening.
        var impossible Event
        impossible.day_number = 12
        fmt.Println(impossible.day_number)
}

2 个答案:

答案 0 :(得分:1)

您可以使用其他包隐藏成员字段。这限制了从该包创建结构到函数的方法,然后您可以控制这些函数以接受一组有限的输入。

foo/foo.go

package foo

import "fmt"

type entity int

const (
    one entity = iota + 1
    two
)

type Foo struct {
    e entity
}

func (f Foo) Get() int {
    return int(f.e)
}

func NewFoo(i int) Foo {
    switch i {
    case 1:
        return Foo{one}
    case 2:
        return Foo{two}
    default:
        panic(fmt.Errorf("%s", "foo"))
    }
}

bar.go

package main

import "fmt"
import "./foo"

func main() {
    f := foo.NewFoo(2)
    fmt.Println(f.Get())
    e := foo.Foo{3}  // Error: implicit assignment of unexported field 'e' in foo.Foo literal
    fmt.Println(e.Get())
    d := foo.NewFoo(3) // panic: foo!
    fmt.Println(d.Get())
}

您无法在Foo包之外创建foo结构,并且在Foo包中创建foo结构的唯一函数只接受一组有限的值

答案 1 :(得分:0)

我不确定这是否有意义,因为您的day_number字段已无法在您的包裹外访问。

但是,如果确实有必要,您可以通过验证输入的方法设置私有字段,例如下面的SetDay方法:

func (d Day) String() string {
    if v, ok := map[Day]string{
        Monday:    "Monday",
        Tuesday:   "Tuesday",
        Wednesday: "Wednesday",
        Thursday:  "Thursday",
        Friday:    "Friday",
        Saturday:  "Saturday",
        Sunday:    "Sunday",
    }[d]; ok {
        return v
    }
    return "Bad day"
}

func (e *Event) SetDay(d Day) error {
    if v := d.String(); v == "Bad day" {
        return fmt.Errorf(v)
    }
    e.day_number = d
    return nil
}

Playground link