繁体   English   中英

使用 csv 在单值上下文中处理多值读取

[英]handling multiple-value in single-value context with csv read

试图从 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( 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:  ...
}

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

解决方案制作一个单独的 function 读取 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) }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM