最佳的字符串转枚举方法是什么?

7

我有一个以下的枚举

type Capability int

const (
    Read   Capability = iota // Read   = 0
    Create                   // Create = 1
    Update                   // Update = 2
    Delete                   // Delete = 3
    List                     // List   = 4
)

我希望能够获取枚举的字符串表示 并且 解析字符串以获取枚举。

我按以下方式从枚举中获取字符串。


capabilityStrs := []string{"read", "create", "update", "delete", "list"}
func (c Capability) String() string {
    return capabilityStrs[c]
}

我该如何将一个字符串解析成枚举类型,使调用ParseString("read")时得到Read?最佳方法是什么?


3
我会选择一个 map[string]Capability - super
谢谢!我已经完成了,但这是处理枚举与字符串表示的最佳方式吗? - prnvbn
1
@prnvbn:什么是“定义”最佳方式的标准?您是否有一些性能限制? - Inian
@Inian认为“最好”这个词的选择不太恰当,我希望能找到一种在Go语言中定义枚举类型的惯用方式。 - prnvbn
1
@prnvbn:如第一条评论中所述的地图方法是 the 惯用方法。 - Inian
1
请勿编辑您的问题以包含答案。回答自己的问题是完全可以的,但请通过在下面添加答案来这样做。 - Jonathan Hall
3个回答

9

根据@super的评论进行回答

var (
    capabilitiesMap = map[string]Capability{
        "read":   Read,
        "create": Create,
        "update": Update,
        "delete": Delete,
        "list":   List,
    }
)
func ParseString(str string) (Capability, bool) {
    c, ok := capabilitiesMap[strings.ToLower(str)]
    return c, ok
}


3
将地图移出函数,无需每次重新初始化。 - user4466350

4

这种方法比顶部答案更好,因为如果你有很多枚举,你不需要两次编写列表(与顶部答案不同):

package usstates

type USState int

//go:generate stringer -type=USState
const (
    Alabama USState = iota
    Alaska
    Arizona
    Arkansas
    California
    Colorado
    Connecticut
    Delaware
    Florida
    Georgia
    Hawaii
    Idaho
    Illinois
    Indiana
    Iowa
    Kansas
    Kentucky
    Louisiana
    Maine
    Maryland
    Massachusetts
    Michigan
    Minnesota
    Mississippi
    Missouri
    Montana
    Nebraska
    Nevada
    NewHampshire
    NewJersey
    NewMexico
    NewYork
    NorthCarolina
    NorthDakota
    Ohio
    Oklahoma
    Oregon
    Pennsylvania
    RhodeIsland
    SouthCarolina
    SouthDakota
    Tennessee
    Texas
    Utah
    Vermont
    Virginia
    Washington
    WestVirginia
    Wisconsin
    Wyoming
)

var MapEnumStringToUSState = func() map[string]USState {
    m := make(map[string]USState)
    for i := Alabama; i <= Wyoming; i++ {
        m[i.String()] = i
    }
    return m
}()

2
“最佳方式”的定义如@inian所说,因人而异。下面是其中一种方法。”
type Capability string

const (
    Read   Capability = "READ"
    Create Capability = "CREATE"
    Update Capability = "UPDATE"
    Delete Capability = "DELETE"
    List   Capability = "LIST"
)

func (c Capability)String()string{
    return string(c)
}

func ParseCapability(s string)(c Capability,err error){
    capabilities := map[Capability]struct{}{
        Read: {},
        Create: {},
        Update: {},
        Delete: {},
        List: {},
    }

    cap := Capability(s)
    _,ok := capabilities[cap]
    if !ok{
        return c,fmt.Errorf(`cannot parse:[%s] as capability`,s)
    }
    return cap,nil
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接