【问题标题】:How to Unmarshal float64 records in database to create insert如何解组数据库中的 float64 记录以创建插入
【发布时间】:2019-11-11 19:55:38
【问题描述】:

我正在处理的项目应该读取一个文件,然后根据该文件生成插入。 现在,脚本有效(有点)。 在为表创建结构时遇到了一个问题,特别是对于 float64 的字段。 我编写的脚本说明了 stringint 类型的字段。我可以插入具有这些字段类型的表中,但是如果我的数据库中有一个浮点字段,则脚本不会插入任何数据。 以下是我的脚本当前设置为检查 int 和 string 类型的方式。

func UnmarshalCsvRecord(readerTest *csv.Reader, v interface{}) error {
    recordtest, err := readerTest.Read()
    if err != nil {
        return err
    }
    s := reflect.ValueOf(v).Elem()
    if s.NumField() != len(recordtest) {
        return &CheckField{s.NumField(), len(recordtest)}
    }
    for i := 0; i < s.NumField(); i++ {
        f := s.Field(i)
        switch f.Type().String() {
        case "string":
            f.SetString(recordtest[i])
        case "int":
            ival, err := strconv.ParseInt(recordtest[i], 10, 0)
            if err != nil {
                return err
            }
            f.SetInt(ival)
        default:
            return &UnsupportedCheck{f.Type().String()}
        }
    }
    return nil
}

type CheckField struct {
    expected, found int
}

func (e *CheckField) Error() string {
    return "CSV line fields mismatch. Expected " + strconv.Itoa(e.expected) + " found " + strconv.Itoa(e.found)
}

type UnsupportedCheck struct {
    TypeCheck string
}

func (e *UnsupportedCheck) Error() string {
    return "Unsupported type: " + e.TypeCheck
}

我可以做些什么来解释我的结构中的 float64 字段?

type ClientSalesTable struct {
    ID int `csv:"id"`
    Amount float64 `csv:"amount"`
    ClientName string `csv:"clientName"`
}

【问题讨论】:

  • 关于您的实现的一个小建议:将开关条件更改为f.Type().Kind() 并在您的开关案例中使用Kind 常量。

标签: go


【解决方案1】:

使用与整数相同的模式处理浮点数。将strconv.ParseInt 替换为strconv.ParseFloat。将f.SetInt(ival) 替换为f.SetFloat(fval)

额外修复:打开 f.Type().Kind() 而不是字符串。

func UnmarshalCsvRecord(readerTest *csv.Reader, v interface{}) error {
    recordtest, err := readerTest.Read()
    if err != nil {
        return err
    }
    s := reflect.ValueOf(v).Elem()
    if s.NumField() != len(recordtest) {
        return &CheckField{s.NumField(), len(recordtest)}
    }
    for i := 0; i < s.NumField(); i++ {
        f := s.Field(i)
        switch f.Type().Kind() {
        case reflect.String:
            f.SetString(recordtest[i])
        case reflect.Int:
            ival, err := strconv.ParseInt(recordtest[i], 10, f.Type().Bits())
            if err != nil {
                return err
            }
            f.SetInt(ival)
        case reflect.Float64:
            fval, err := strconv.ParseFloat(recordtest[i], f.Type().Bits())
            if err != nil {
                return err
            }
            f.SetFloat(fval)
        default:
            return &UnsupportedCheck{f.Type().String()}
        }
    }
    return nil
}

通过添加更多的情况,上面的代码可以扩展为处理所有整数和浮点类型:

switch f.Type().Kind() {
...
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
...
case reflect.Float64, reflect.Float32:
...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    相关资源
    最近更新 更多