csv, json,time包的学习(二)
一、CSV
1.type Reader
type Reader struct {
Comma rune //指定分割符号,默认为","
Comment rune //指定忽略本行的符号,如忽略注释
}
eg:
package main
import (
"encoding/csv"
"fmt"
"log"
"strings"
)
func main() {
in := `first_name;last_name;username
"Rob";"Pike";rob
# lines beginning with a # character are ignored
Ken;Thompson;ken
"Robert";"Griesemer";"gri"
`
r := csv.NewReader(strings.NewReader(in))
r.Comma = ';'
r.Comment = '#'
records, err := r.ReadAll()
if err != nil {
log.Fatal(err)
}
fmt.Print(records)
}
Output
[[first_name last_name username] [Rob Pike rob] [Ken Thompson ken] [Robert Griesemer gri]]
2.func (*Reader) FieldPos 1.17新加入
func (r * Reader ) FieldPos(field int ) (line, column int )
新的Reader.FieldPos方法返回对应于开始的行和列最近返回的记录中的给定字段Read.
3.Writer
type Writer struct {
Comma rune // 字段分隔符(由 NewWriter 设置为 ',')
UseCRLF bool // True 使用 \r\n 作为行终止符
// 包含过滤或未导出的字段
}
eg:
import (
"encoding/csv"
"log"
"os"
)
func main() {
records := [][]string{
{"first_name", "last_name", "username"},
{"Rob", "Pike", "rob"},
{"Ken", "Thompson", "ken"},
{"Robert", "Griesemer", "gri"},
}
w := csv.NewWriter(os.Stdout)
for _, record := range records {
if err := w.Write(record); err != nil {
log.Fatalln("error writing record to csv:", err)
}
}
// Write any buffered data to the underlying writer (standard output).
w.Flush()
if err := w.Error(); err != nil {
log.Fatal(err)
}
}
func NewWriter(w io . Writer ) * Writer
func (w * Writer ) Error()error
func (w * Writer ) Flush()
func (w * Writer ) Write(record [] string )error
func (w * Writer ) WriteAll(records [][] string )error
二、json的使用
1.讲json数据转化为加prefix前缀和根据indent进行换行的字符串
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
package main
import (
"bytes"
"encoding/json"
"log"
"os"
)
eg:
func main() {
type Road struct {
Name string
Number int
}
roads := []Road{
{"Diamond Fork", 29},
{"Sheep Creek", 51},
}
b, err := json.Marshal(roads)
if err != nil {
log.Fatal(err)
}
var out bytes.Buffer
json.Indent(&out, b, "=", "\t")
out.WriteTo(os.Stdout)
}
- func Marshal 返回 v 的 JSON 编码。
- Marshal 递归地遍历值 v。如果遇到的值实现了 Marshaler 接口并且不是 nil 指针,Marshal 将调用其 MarshalJSON 方法来生成 JSON。如果不存在 MarshalJSON 方法但该值实现了 encoding.TextMarshaler,Marshal 将调用其 MarshalText 方法并将结果编码为 JSON 字符串。nil 指针异常并不是绝对必要的,但在 UnmarshalJSON 的行为中模仿了类似的必要异常。
func Marshal(v interface{}) ([]byte, error)
// Field appears in JSON as key "myName".
字段在json中显示的值为myName
Field int `json:"myName"`
// Field appears in JSON as key "myName" and
// the field is omitted from the object if its value is empty,
// as defined above.
字段在json中现实的值为myName,如果该字段为空,则忽略该字段
Field int `json:"myName,omitempty"`
// Field appears in JSON as key "Field" (the default), but
// the field is skipped if empty.
// Note the leading comma.注意逗号
Field int `json:",omitempty"`
// Field is ignored by this package.在这个包里忽略该字段
Field int `json:"-"`
// Field appears in JSON as key "-".字段在json中显示的键为“-”
//Note the leadingc comma. 注意逗号
Field int `json:"-,"`
3.func MarshalIndent MarshalIndent 类似于Marshal,但应用缩进来格式化输出。根据缩进嵌套,输出中的每个 JSON元素将以前缀开头的新行开始,后跟一个或多个缩进副本。
func MarshalIndent(v interface{}, prefix, indent string ) ([] byte , error )
4.func Unmarshal解码字符串
func Unmarshal(data []byte, v interface{}) error
5.dec解码器的方法
func Valid(data [] byte ) bool //有效报告数据是否为有效的 JSON 编码。
//解码器在目标是结构并且输入包含与目标中任何未忽略的导出字段不匹配的对象键时返回错误。
func (dec * Decoder ) DisallowUnknownFields()
//返回当前解码器位置的输入流字节偏移量。偏移量给出了最近返回的标记的结束位置和下一个标记的开始位置。
func (dec *Decoder) InputOffset() int64
//判断当前解码器是否还有下一个元素
func (*Decoder) More
//令牌返回输入流中的下一个 JSON 令牌。在输入流的末尾,Token 返回 nil,io.EOF。
Token 保证它返回的分隔符 [ ] { } 正确嵌套和匹配:如果 Token 在输入中遇到意外的分隔符,它将返回错误
func (dec *Decoder) Token() (Token, error)
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"strings"
)
func main() {
const jsonStream = `
{"Message": "Hello", "Array": [1, 2, 3], "Null": null, "Number": 1.234}
`
dec := json.NewDecoder(strings.NewReader(jsonStream))
for {
t, err := dec.Token()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("%T: %v", t, t)
if dec.More() {
fmt.Printf(" (more)")
}
fmt.Printf("\n")
}
}
6.编码器的介绍和使用
type Encoder struct {
// 包含过滤或未导出的字段
}
func NewEncoder
//NewEncoder 返回一个写入 w 的新编码器。
func NewEncoder(w io . Writer ) *Encoder
//Encode 将 v 的 JSON 编码写入流,后跟换行符。
func (enc * Encoder ) Encode(v interface{})错误
func (enc * Encoder ) SetIndent(prefix, indent string )
SetIndent 指示编码器将每个后续编码值格式化为由包级函数 Indent(dst, src, prefix, indent) 缩进。调用 SetIndent("", "") 禁用缩进。
解码器的编码和解码中json.RawMessage
eg:
package main
import (
"encoding/json"
"fmt"
"os"
)
func main() {
h := json.RawMessage(`{"precomputed": true}`)
c := struct {
Header *json.RawMessage `json:"header"`
Body string `json:"body"`
}{Header: &h, Body: "Hello Gophers!"}
b, err := json.MarshalIndent(&c, "", "\t")
if err != nil {
fmt.Println("error:", err)
}
os.Stdout.Write(b)
}
eg:
package main
import (
"encoding/json"
"fmt"
"log"
)
func main() {
type Color struct {
Space string
Point json.RawMessage // delay parsing until we know the color space
}
type RGB struct {
R uint8
G uint8
B uint8
}
type YCbCr struct {
Y uint8
Cb int8
Cr int8
}
var j = []byte(`[
{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}},
{"Space": "RGB", "Point": {"R": 98, "G": 218, "B": 255}}
]`)
var colors []Color
err := json.Unmarshal(j, &colors)
if err != nil {
log.Fatalln("error:", err)
}
for _, c := range colors {
var dst interface{}
switch c.Space {
case "RGB":
dst = new(RGB)
case "YCbCr":
dst = new(YCbCr)
}
err := json.Unmarshal(c.Point, dst)
if err != nil {
log.Fatalln("error:", err)
}
fmt.Println(c.Space, dst)
}
}
三、time包
时间包提供测量和显示时间的功能。
func After After
等待持续时间过去,然后在返回的通道上发送当前时间。它相当于 NewTimer(d).C。在计时器触发之前,垃圾收集器不会恢复底层计时器。如果需要考虑效率,请改用 NewTimer 并在不再需要计时器时调用 Timer.Stop。
func After(d Duration ) <-chan Time
eg:
package main
import (
"fmt"
"time"
)
var c chan int
func handle(int) {}
func main() {
select {
case m := <-c:
handle(m)
case <-time.After(10 * time.Second):
fmt.Println("timed out")
}
}
func Tick(d Duration ) <-chan Time
Tick 是 NewTicker 的便捷包装器,仅提供对滴答通道的访问。尽管 Tick 对不需要关闭 Ticker 的客户端很有用,但请注意,如果无法关闭它,则垃圾收集器无法恢复底层的 Ticker;它“泄漏”。与 NewTicker 不同,如果 d <= 0,Tick 将返回 nil。
package main
import (
"fmt"
"time"
)
func statusUpdate() string { return "" }
func main() {
c := time.Tick(5 * time.Second)
for next := range c {
fmt.Printf("%v %s\n", next, statusUpdate())
}
}
func ParseDuration
ParseDuration 解析持续时间字符串。持续时间字符串是一个可能有符号的十进制数序列,每个都有可选的分数和单位后缀,例如“300ms”、“-1.5h”或“2h45m”。有效时间单位为“ns”、“us”(或“µs”)、“ms”、“s”、“m”、“h”。
func ParseDuration(s string) (Duration, error)
package main
import (
"fmt"
"time"
)
func main() {
hours, _ := time.ParseDuration("10h")
complex, _ := time.ParseDuration("1h10m10s")
micro, _ := time.ParseDuration("1µs")
// The package also accepts the incorrect but common prefix u for micro.
micro2, _ := time.ParseDuration("1us")
fmt.Println(hours)
fmt.Println(complex)
fmt.Printf("There are %.0f seconds in %v.\n", complex.Seconds(), complex)
fmt.Printf("There are %d nanoseconds in %v.\n", micro.Nanoseconds(), micro)
fmt.Printf("There are %6.2e seconds in %v.\n", micro2.Seconds(), micro)
}
函数
func Since(t Time) Duration 从t依赖到现在经过的时间,time.Now().Sub(t).的简写
func Until(t Time) Duration 直到返回直到 t 的持续时间。它是 t.Sub(time.Now()) 的简写。
func (d Duration) Truncate(m Duration) Duration 截断,根据m进行截断t
func (d Duration) Round(m Duration) Duration Round 将四舍五入 d 的结果返回到最接近的 m 倍数。
时区
package main
import (
"fmt"
"time"
)
func main() {
// China doesn't have daylight saving. It uses a fixed 8 hour offset from UTC.
secondsEastOfUTC := int((8 * time.Hour).Seconds())
beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
// If the system has a timezone database present, it's possible to load a location
// from that, e.g.:
// newYork, err := time.LoadLocation("America/New_York")
// Creating a time requires a location. Common locations are time.Local and time.UTC.
timeInUTC := time.Date(2009, 1, 1, 12, 0, 0, 0, time.UTC)
sameTimeInBeijing := time.Date(2009, 1, 1, 20, 0, 0, 0, beijing)
// Although the UTC clock time is 1200 and the Beijing clock time is 2000, Beijing is
// 8 hours ahead so the two dates actually represent the same instant.
timesAreEqual := timeInUTC.Equal(sameTimeInBeijing)
fmt.Println(timesAreEqual)
}
var Local *Location = &localLoc
var UTC *Location = &utcLoc //时间协调时间
输入月份
package main
import (
"fmt"
"time"
)
func main() {
_, month, day := time.Now().Date()
if month == time.November && day == 10 {
fmt.Println("Happy Go day!")
}
}
\\String 返回月份的英文名称(“January”、“February”、...)。
func (m Month ) String() string
滴答器/定时器
Ticker结构体
type Ticker struct {
C <-chan Time // 传递
报价的通道。// 包含过滤或未导出的字段
}
//返回一个新的定时器
func NewTicker(d Duration) *Ticker
eg:
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
done := make(chan bool)
go f.Second)
done <- trueunc() {
time.Sleep(10 * time
}()
for {
select {
case <-done:
fmt.Println("Done!")
return
case t := <-ticker.C:
fmt.Println("Current time: ", t)
}
}
}
重置滴答器为指定时间d
func (t *Ticker) Reset(d Duration)
func (t *Ticker) Stop() //停止滴答器
定时器
type Timer struct {
C <-chan Time
// 包含过滤或未导出的字段
}
//定义一个新的定时器
func AfterFunc(d Duration , f func()) *Timer
//重置定时器
func (t * Timer ) Reset(d Duration ) bool
func (t * Timer ) Stop() bool //停止定时器