go - 使用csv read在单值上下文中处理多值

标签 go

尝试从csv文件读取datenumber,所以我有以下结构

type Transaction struct {
    Warehouse string    `json:"warehouse"`
    Item      string    `json:"item"`
    Movement  string    `json:"movement"`
    Batch     string    `json:"batch"`
    Date      time.Time `json:"transaction_data"`
    Quantity  uint64    `json:"quantity"`
}

type Transactions struct {
    header []string
    lines  []Transaction
}

并进行如下阅读:

func main() {
    // Reading csv file thread > START //
    pairs := []Pair{{"m", 1}, {"d", 0}, {"c", 2}}
    fmt.Println(pairs)
    // Sort by Key
    sort.Sort(ByKey(pairs))
    fmt.Println(pairs)
    pairs = append(pairs, Pair{"h", 5})
    fmt.Println(pairs)

    // Reading csv file thread > START //
    input := make(chan Transactions)
    go func(input_file string) {
        var trx Transactions
        fr, err := os.Open(input_file)
        failOnError(err)
        defer fr.Close()
        r := csv.NewReader(fr)
        rows, err := r.ReadAll()
        failOnError(err)
        trx.header = rows[0]
        for _, row := range rows[1:] {
            trx.lines = append(trx.lines, Transaction{
                Warehouse: strings.TrimSpace(row[0]),
                Item:      strings.TrimSpace(row[1]),
                Movement:  strings.TrimSpace(row[2]),
                Batch:     strings.TrimSpace(row[3]),
                Date:      time.Parse("%Y-%m-%d", row[4]),                   // multiple-value in single-value context error
                Quantity:  (strconv.ParseFloat(row[5], 64) * 1000).(uint64),  // multiple-value in single-value context error
            })
        }

        peopleJson, _ := json.Marshal(trx.lines)
        fmt.Println(string(peopleJson)) 

        input <- trx // send data to channel read
    }("trx.csv")
    <-input // rceive from channel 'read' and assign value to new data variable
    // Reading csv file thread < END //
}

并得到2个错误:

.\pair.go:73:24: multiple-value time.Parse() in single-value context
.\pair.go:74:34: multiple-value strconv.ParseFloat() in single-value context

我了解原因,这是time.Parse()strconv.ParseFloat()返回2个输出(值和错误)的原因,可以通过编写以下代码来解决此问题:
date, _ := time.Parse("%Y-%m-%d", row[4])
// and later:
Date:      date,

但是我想知道是否可以避免这种情况,并在同一命令块中解决它:

trx.lines = append(trx.lines, Transaction{
                Warehouse: strings.TrimSpace(row[0]),
                Item:      strings.TrimSpace(row[1]),
                Movement:  strings.TrimSpace(row[2]),
                Batch:     strings.TrimSpace(row[3]),
                Date:      ...
                Quantity:  ...
}

最佳答案

我得到了答案(感谢富有成效的评论,只有富有成效的评论)

制作一个单独的函数的解决方案,该函数读取2个上下文,并仅按如下所示返回值:

func mustTime(t time.Time, err error) time.Time { failOnError(err); return t }
func mustNumber(d float64, err error) uint64    { failOnError(err); return uint64(d + 1000) }

然后将其称为:

Date:      mustTime(time.Parse("%Y-%m-%d", row[4])),
Quantity:  mustNumber(strconv.ParseFloat(row[5], 64)),

因此,完整的正确代码变为:

package main

import (
    "encoding/csv"
    "encoding/json"
    "fmt"
    "log"
    "os"
    "sort"
    "strconv"
    "strings"
    "time"
)

func failOnError(err error) {
    if err != nil {
        log.Fatal("Error:", err)
        panic(err)
    }
}

type Pair struct {
    Key   string
    Value float64
}

type ByKey []Pair

func (s ByKey) Len() int {
    return len(s)
}

func (s ByKey) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}

func (s ByKey) Less(i, j int) bool {
    return s[i].Key < s[j].Key
}

func (s ByKey) pop() bool {
    //s = append(s,[0 : s.Len()-1])
    return true
}

func main() {
    // Reading csv file thread > START //
    pairs := []Pair{{"m", 1}, {"d", 0}, {"c", 2}}
    fmt.Println(pairs)
    // Sort by Key
    sort.Sort(ByKey(pairs))
    fmt.Println(pairs)
    pairs = append(pairs, Pair{"h", 5})
    fmt.Println(pairs)

    // Reading csv file thread > START //
    input := make(chan Transactions)
    go func(input_file string) {
        var trx Transactions
        fr, err := os.Open(input_file)
        failOnError(err)
        defer fr.Close()
        r := csv.NewReader(fr)
        rows, err := r.ReadAll()
        failOnError(err)
        trx.header = rows[0]
        for _, row := range rows[1:] {
            trx.lines = append(trx.lines, Transaction{
                Warehouse: strings.TrimSpace(row[0]),
                Item:      strings.TrimSpace(row[1]),
                Movement:  strings.TrimSpace(row[2]),
                Batch:     strings.TrimSpace(row[3]),
                Date:      mustTime(time.Parse("%Y-%m-%d", row[4])),
                Quantity:  mustNumber(strconv.ParseFloat(row[5], 64)),
            })
        }

        peopleJson, _ := json.Marshal(trx.lines)
        fmt.Println(string(peopleJson)) // This is working smoothly

        input <- trx // send data to channel read
    }("trx.csv")
    //data :=
    <-input // rceive from channel 'read' and assign value to new data variable
    // Reading csv file thread < END //
}

type Transactions struct {
    header []string
    lines  []Transaction
}

type Transaction struct {
    Warehouse string    `json:"warehouse"`
    Item      string    `json:"item"`
    Movement  string    `json:"movement"`
    Batch     string    `json:"batch"`
    Date      time.Time `json:"transaction_data"`
    Quantity  uint64    `json:"quantity"`
}

func mustTime(t time.Time, err error) time.Time { failOnError(err); return t }
func mustNumber(d float64, err error) uint64    { failOnError(err); return uint64(d + 1000) }

关于go - 使用csv read在单值上下文中处理多值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62177662/

相关文章:

linux - 无法在 Linux 上的 goroutine 中运行 go web serve (Mint)

go - 如何在golang中更改指针 slice

http - 如何在 Go 中使用 application/x-www-form-urlencoded content-type 执行 GET 请求?

sql - 如何使用 go-mssqldb 修复 Go 中的错误 mssql : Error converting data type decimal to nvarchar.

go - 在自己的原型(prototype)上导入 vendor 原型(prototype)

go - 访问 GO 结构中的字段

google-app-engine - 使用 Go on App Engine Standard 调用系统包

database - 具有$ setIntersection的Mongodb聚合管道

go - 如何在数组列表中保存[] byte数据

function - 如何理解这个递归结果