将字符串解析为枚举的最佳方法

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

Best way to parse a string to an enum

问题

我有一个如下所示的枚举类型:

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?有什么最佳方法可以实现这个需求?

英文:

I have an enum as follows

type Capability int

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

I want to be able to get the string representation from the enum AS WELL AS parse a string to get the enum.

I get the string from the enum as follows.


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

How do I parse a string into an enum such that a call to ParseSTring("read") gives me Read`. What is the Best way to go about this?

答案1

得分: 8

根据@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
}

根据@super的评论提供的答案,这段代码定义了一个名为capabilitiesMap的映射,将字符串与Capability类型的值进行关联。然后,ParseString函数接受一个字符串作为参数,并尝试在capabilitiesMap中查找对应的值。如果找到了对应的值,则返回该值和true;否则,返回零值和false

英文:

Answer based on the comment by @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
}

答案2

得分: 3

这比最佳答案更好,因为如果你有很多枚举值,你不需要写两次列表(与最佳答案不同):

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
}()
英文:

This is better than the top answer since if you have a ton of enums, you don't have to write out the list twice (unlike top answer):

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 &lt;= Wyoming; i++ {
		m[i.String()] = i
	}
	return m
}()

答案3

得分: 1

以下是翻译好的内容:

虽然“最佳方式”的定义是可变的,就像@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
}

希望对你有帮助!

英文:

Whereas what defines 'best way' is dependable like @inian says, following is one approach

type Capability string

const (
	Read   Capability = &quot;READ&quot;
	Create Capability = &quot;CREATE&quot;
	Update Capability = &quot;UPDATE&quot;
	Delete Capability = &quot;DELETE&quot;
	List   Capability = &quot;LIST&quot;
)

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
}

huangapple
  • 本文由 发表于 2021年7月27日 18:55:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/68543604.html
匿名

发表评论

匿名网友

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

确定