go - 使用 csv 读取处理单值上下文中的多值
问题描述
试图从 csv 文件中读取date
和读取number
,所以我有以下结构
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
我理解原因,即返回 2 个输出、值time.Parse()
和strconv.ParseFloat()
错误,并且可以通过编写以下内容来克服这个问题:
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) }
推荐阅读
- java - Spring Boot Maven 模块化构建
- flutter - Flutter Bloc - 有没有办法在屏幕中提供不同的块实例
- android - 如何从分页源或远程调解器 Kotlin 调用不同的 api 资源
- python - Sqlite 拆分字符串并从父文件夹获取 rowid
- python - 如何将此数据存储到 django 会话中
- javascript - 如何使用 node.js(express) API 调用访问搜索参数并在反应前端提供服务
- ruby-on-rails - 在 Rails 的 rspec 中,我如何编写/编辑我的测试文件,以便特定上下文中的示例以设定的顺序运行?
- r - R:使用样条重复交叉验证 - 错误
- sql - Cognos 报告同一日期的总值
- ruby-on-rails - Rails Dockerfile 不再构建,无法安装 racc