我有一个constutil包,其中我使用iota定义了一些常量值。
package constutil
type UserType uint
const (
Free UserType = iota + 1
Premium UserType
...
)我将从json获取{"user": "Premium", ...}。现在我需要保存用户的值,就像Premium的值是2一样。我尝试像这样获取值:
constutil.(req.User)但是当req.User返回一个类似于:"Premium"的string时,它并不起作用。
我可以使用map[string]uint来完成。但是有没有什么方法可以用iota来实现呢?
发布于 2019-02-18 00:44:07
不要认为在iota值和字符串之间有任何内置的映射方式。有一些工具可以生成用于执行映射的代码。
我曾经遇到过类似的情况,当我不想依赖生成器或其他工具时,我也做过类似的事情。希望它能作为一些东西的开始。
https://play.golang.org/p/MxPL-0FVGMt
package main
import (
"encoding/json"
"fmt"
)
type UserType uint
const (
UserTypeFree UserType = iota
UserTypePremium
)
var UserTypeToString = map[UserType]string{
UserTypeFree: "Free",
UserTypePremium: "Premium",
}
var UserTypeFromString = map[string]UserType{
"Free": UserTypeFree,
"Premium": UserTypePremium,
}
func (ut UserType) String() string {
if s, ok := UserTypeToString[ut]; ok {
return s
}
return "unknown"
}
func (ut UserType) MarshalJSON() ([]byte, error) {
if s, ok := UserTypeToString[ut]; ok {
return json.Marshal(s)
}
return nil, fmt.Errorf("unknown user type %d", ut)
}
func (ut *UserType) UnmarshalJSON(text []byte) error {
var s string
if err := json.Unmarshal(text, &s); err != nil {
return err
}
var v UserType
var ok bool
if v, ok = UserTypeFromString[s]; !ok {
return fmt.Errorf("unknown user type %s", s)
}
*ut = v
return nil
}
func main() {
var ut UserType
json.Unmarshal([]byte(`"Free"`), &ut)
fmt.Printf("%#v %v \n", ut, ut)
b, _ := json.Marshal(ut)
fmt.Printf("%v\n", string(b))
}发布于 2019-02-18 00:24:34
对于这种枚举用例,最好使用常量字符串。
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))
}https://stackoverflow.com/questions/54735113
复制相似问题