如何使结构体字段成为列表中的值?

huangapple go评论89阅读模式
英文:

How to make a struct field be a value from list?

问题

我有一个访问权限列表:

const (
    Everyone = 0
    Owner = 1
    Administrator = 2
)

还有一个表示路由的结构体:

type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
    AccessLevel uint64
}

如何限制Route结构体中的AccessLevel字段值只能是上述常量之一?

英文:

I have a list of access rights:

const (
    Everyone = 0
    Owner = 1
    Administrator = 2
)

And a struct representing Routes:

type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
    AccessLevel uint64
}

How can I restrict AccessLevel field value of the Route struct be only one of those const from above?

答案1

得分: 1

这种限制的唯一方法是不导出该字段,并在任何setter方法中进行检查。

type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
    accessLevel uint64
}

// AccessLevel的getter方法
func (r Route) AccessLevel() uint64 {
  return r.accessLevel
}

// SetAccessLevel的setter方法
func (r Route) SetAccessLevel(value uint64) error {
    if value < 0 || value > 2 {
        return errors.New("AccessLevel必须介于0和2之间(包括0和2)")
    }
    r.accessLevel = value
    return nil
}
英文:

The only way to impose this type of restriction is by not exporting the field, and doing your checks in any setter method(s).

type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
    accessLevel uint64
}

// AccessLevel getter method
func (r Route) AccessLevel() uint64 {
  return r.accessLevel
}

// SetAccessLevel setter method
func (r Route) SetAccessLevel(value uint64) error {
    if value &lt; 0 || value &gt; 2 {
        return errors.New(&quot;AccessLevel must be between 0 and 2, inclusive&quot;)
    }
    r.accessLevel = value
    return nil
}

答案2

得分: 0

你不能这样做。Go语言不支持枚举类型。不过,你可以接近实现它。只需为你的访问级别引入一个单独的类型:

type AccessLevel uint64

并将常量定义为该类型:

const (
    Everyone      AccessLevel = 0
    Owner                     = 1
    Administrator             = 2
)

然后将字段定义为该类型:

type Route struct {
    // ...
    AccessLevel AccessLevel
}

现在你可以将这些常量赋值给AccessLevel类型的变量,但不能赋值给一个“普通”的uint64类型的变量。

需要注意的是,你仍然可以通过类型转换将uint64转换为AccessLevel类型,例如AccessLevel(1234)

英文:

You can't. Go doesn't support enums. However, you can get close to it. Just introduce a separate type for your access level:

type AccessLevel uint64

and make the consts be of the type:

const (
	Everyone      AccessLevel = 0
	Owner                     = 1
	Administrator             = 2
)

Then define the Field to be of that type:

type Route struct {
    // ...
    AccessLevel AccessLevel
}

Now you can assign those consts, but not a "normal" uint64.

The caveat is that you can still type convert a uint64 to a AccessLevel via AccessLevel(1234).

huangapple
  • 本文由 发表于 2017年2月24日 15:39:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/42433162.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定