String 如何使用json字符串值获取iota值?
我有一个constutil包,其中我使用iota定义了一些const值String 如何使用json字符串值获取iota值?,string,go,iota,String,Go,Iota,我有一个constutil包,其中我使用iota定义了一些const值 package constutil type UserType uint const ( Free UserType = iota + 1 Premium UserType ... ) 从json我将得到{“user”:“Premium”,…}。现在我需要保存用户的值,如Premium的2。我试图获得如下值: constutil.(req.User) 但是它不能像req那样工作。用户返回一个字
package constutil
type UserType uint
const (
Free UserType = iota + 1
Premium UserType
...
)
从json
我将得到{“user”:“Premium”,…}
。现在我需要保存用户的值,如Premium
的2
。我试图获得如下值:
constutil.(req.User)
但是它不能像req那样工作。用户
返回一个字符串
,比如:“Premium”
我可以使用
map[string]uint
来完成。但是,是否有任何方法可以使用iota
?对于这样的枚举用例,最好使用const string
type UserType string
const(
Premium UserType = "Premium"
)
或者定义自定义封送/取消封送:
package main
import (
"fmt"
"encoding/json"
)
type UserType uint
func (u UserType) String() string{
return "Premium"
}
const(
Premium UserType = 1
)
type User struct{
T UserType `json:"type"`
}
func (u *User) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
T string
}{
T: fmt.Sprint(u.T),
})
}
func (u *User) UnmarshalJSON(data []byte) error {
aux := &struct {
T string `json:"type"`
}{ }
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
fmt.Println(aux.T)
switch aux.T{
case "Premium":
u.T = Premium
}
return nil
}
func main() {
b := []byte(`{"type":"Premium"}`)
x := new(User)
if err := json.Unmarshal(b, x); err != nil{
fmt.Printf("err: %v\n", err)
}
fmt.Printf("unmasrshalled: %v\n", *x)
fmt.Printf("type: %d\n", x.T)
b, _ = json.Marshal(x)
fmt.Printf("marshalled: %v\n", string(b))
}
不要认为在
iota
值和字符串之间存在任何内置的映射方式。有一些工具可以生成用于进行映射的代码
我也遇到过类似的情况,当我不想依赖生成器或其他工具时,我也做过类似的事情。希望这能成为一个开始
主程序包
进口(
“编码/json”
“fmt”
)
类型用户类型uint
常数(
UserTypeFree UserType=物联网
用户类型溢价
)
var UserTypeToString=map[UserType]字符串{
UserTypeFree:“免费”,
UserTypePremium:“Premium”,
}
var UserTypeFromString=map[string]UserType{
“Free”:UserTypeFree,
“高级”:用户类型高级,
}
func(ut用户类型)字符串()字符串{
如果s,ok:=UserTypeToString[ut];ok{
返回s
}
返回“未知”
}
func(ut用户类型)MarshalJSON()([]字节,错误){
如果s,ok:=UserTypeToString[ut];ok{
返回json.Marshal
}
返回nil,fmt.Errorf(“未知用户类型%d”,ut)
}
func(ut*UserType)解组JSON(文本[]字节)错误{
var s字符串
如果err:=json.Unmarshal(text,&s);err!=nil{
返回错误
}
var v用户类型
var ok bool
如果v,ok=UserTypeFromString[s];!ok{
返回fmt.Errorf(“未知用户类型%s”,s)
}
*ut=v
归零
}
func main(){
变量ut用户类型
Unmarshal([]字节(`Free`),&ut)
fmt.Printf(“%#v%v\n”,ut,ut)
b、 _u:=json.Marshal(ut)
fmt.Printf(“%v\n”,字符串(b))
}
不知道你在尝试什么。您应该保存“Premium”,而不是2。为什么?因为如果您将2设为安全值,并向包中添加一个常量,则可能2将是免费值。@apxp在用户定义表中Premium
user的ID
为2,我需要保存ID而不是值。我不建议使用两个映射UserType->string
和string->UserType
。相反,只实现一个,并有一个从值中提取键的for
循环。你减少了可能的不一致。是的,很好。如果有很多类型,我可能会以某种方式生成。如果一个类型没有数百个映射,另一个解决方案是只使用一个映射,而在其中一个方向上进行映射时进行迭代。我猜这不会成为您的性能瓶颈。