使用自定义扫描功能汇总枚举类型

发布于 2025-02-12 14:26:07 字数 1814 浏览 0 评论 0原文

我正在尝试删除性别类型,该枚举只是hood下的int64(我不想使用此类型的任何字符串表示形式)。

问题是性别价值无法正确处理,我总是以0结尾。

我缺少一些东西,但我看不到它...

非常感谢。

https://go.dev/play/pplay/p/bfni_espzjy

package main

import (
    "database/sql"
    "encoding/json"
    "fmt"
)

type Person struct {
    name   string `json:"name"`
    gender Gender `json:"gender"`
}

type Gender int64

const (
    Undefined Gender = iota
    Male
    Female
    NonBinary
)

func (g *Gender) Scan(v interface{}) error {
    if v == nil {
        *g = Gender(Undefined)
        return nil
    }

    ns := sql.NullInt64{}
    if err := ns.Scan(v); err != nil {
        return err
    }

    if !ns.Valid {
        return fmt.Errorf("Gender.Scan: column is not nullable")
    }

    if ns.Int64 > 3 {
        return fmt.Errorf("Gender.Scan: gender value > 3")
    }
    *g = genderFromInt64(ns.Int64) // tried Gender(ns.Int64) without success
    return nil
}

// tried genderFromInt64(i int64) instead of Gender(ns.Int64) without success
func genderFromInt64(i int64) Gender {
    switch i {
    case 0:
        return Undefined
    case 1:
        return Male
    case 2:
        return Female
    case 3:
        return NonBinary
    default:
        return Female
    }
}

// Value() is not used yet
func (g Gender) Value() (driver.Value, error) {
    return int64(g), nil
}

func (g Gender) String() string {
    return [...]string{"Undefined", "Male", "Female", "Non-binary"}[g]
}

func main() {
    var person Person
    jsonPerson := `{"name": "John", "gender": 2}`

    json.Unmarshal([]byte(jsonPerson), &person)
    fmt.Printf("%+v", person)
}

I'm trying to unmarshall a Gender type that is an Enumeration that is just int64 under the hood (I don't want to use any string representation of this type).

Problem is that the Gender value is not handled properly, I always ended with 0.

I'm missing something but I don't see it...

Thank you so much.

https://go.dev/play/p/bfnI_ESpzJY

package main

import (
    "database/sql"
    "encoding/json"
    "fmt"
)

type Person struct {
    name   string `json:"name"`
    gender Gender `json:"gender"`
}

type Gender int64

const (
    Undefined Gender = iota
    Male
    Female
    NonBinary
)

func (g *Gender) Scan(v interface{}) error {
    if v == nil {
        *g = Gender(Undefined)
        return nil
    }

    ns := sql.NullInt64{}
    if err := ns.Scan(v); err != nil {
        return err
    }

    if !ns.Valid {
        return fmt.Errorf("Gender.Scan: column is not nullable")
    }

    if ns.Int64 > 3 {
        return fmt.Errorf("Gender.Scan: gender value > 3")
    }
    *g = genderFromInt64(ns.Int64) // tried Gender(ns.Int64) without success
    return nil
}

// tried genderFromInt64(i int64) instead of Gender(ns.Int64) without success
func genderFromInt64(i int64) Gender {
    switch i {
    case 0:
        return Undefined
    case 1:
        return Male
    case 2:
        return Female
    case 3:
        return NonBinary
    default:
        return Female
    }
}

// Value() is not used yet
func (g Gender) Value() (driver.Value, error) {
    return int64(g), nil
}

func (g Gender) String() string {
    return [...]string{"Undefined", "Male", "Female", "Non-binary"}[g]
}

func main() {
    var person Person
    jsonPerson := `{"name": "John", "gender": 2}`

    json.Unmarshal([]byte(jsonPerson), &person)
    fmt.Printf("%+v", person)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

悍妇囚夫 2025-02-19 14:26:07

在您的代码中,我想指出两件事(@Mkopriva已经提到)

  1. 人的字段是未伸出的,并且对unmarshal方法看不到。您可以使用Go Vet命令它将帮助您防止这些错误

  2. 您已经实现了将性别价值从枚举转换为字符串的Stringer接口。如果您不想将此类型表示为字符串,则可以注释字符串方法

    func(g gender)string()字符串{return [...]字符串{“ undefined”,“ male”,“ heapen”,“ nont binary”} [g]}>

https://go.dev/play/p/c1zuv_fes0k

In your code, I want to point out 2 things (which is already mention by @mkopriva)

  1. Person's fields are unexported and are not visible to unmarshal methods. You can use go vet command it will help you to prevent these kinds of errors

  2. You have implemented the Stringer interface which converts Gender value from enum to string. if you don't want to represent this type as a string you can comment String method

    func (g Gender) String() string { return [...]string{"Undefined", "Male", "Female", "Non-binary"}[g] }

https://go.dev/play/p/C1ZUv_fES0k

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文