什么是只允许一组可能选项的数据结构?
我尝试过使用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)
}
答案 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
}