常用API介绍

Catalogue
  1. 1. 日期
  2. 2. 字符串处理
  3. 3. 文件操作
    1. 3.0.1. 读文件
    2. 3.0.2. 写文件
    3. 3.0.3. 读时写
    4. 3.0.4. 用bufio库
    5. 3.0.5. 用ioutil库
    6. 3.0.6. 判断文件是否存在
  • 4. JSON操作
    1. 4.0.1. 编码
    2. 4.0.2. 解码
  • 5. 解析命令行参数
    1. 5.0.1. os.Args
    2. 5.0.2. flag包
  • 6. 单元测试
  • 7. 参考资料
  • 日期

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    package main

    import (
    "fmt"
    "time"
    )

    func main() {

    // 当前日期
    now := time.Now()
    fmt.Printf("now = %v \nnow type=%T\n", now, now)

    fmt.Printf("year=%v\n", now.Year())
    fmt.Printf("hour=%v\n", now.Hour())

    // 格式化日期
    dateStr := fmt.Sprintf("当前年月日 %d-%d-%d %d:%d:%d\n",
    now.Year(), now.Month(), now.Day(),
    now.Hour(), now.Minute(), now.Second())
    fmt.Printf("datestr=%s\n", dateStr)

    // 该字符串各数字都是固定的,可以任意组合成需要的格式,结果为当前时间的该种格式显示
    fmt.Printf(now.Format("2006-01-02 15:04:05"))
    fmt.Println()
    fmt.Printf(now.Format("2006-01-02"))
    fmt.Println()
    fmt.Printf(now.Format("15:04:05"))
    fmt.Println()

    fmt.Printf("unix秒数:%v\n", now.Unix())
    fmt.Printf("unix纳秒数: %v", now.UnixNano())
    }

    字符串处理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    package main

    import (
    "fmt"
    "strconv"
    "strings"
    )

    func main() {
    // 字符串转整数
    n, _ := strconv.Atoi("12")
    fmt.Println("atoi : ", n)

    // 整数转字符串
    str := strconv.Itoa(1234)
    fmt.Println("itoa : ", str)

    // 字符串转[]byte
    var bytes = []byte("hello go")
    fmt.Printf("bytes=%v\n", bytes)

    // []bytes转字符串
    str1 := string([]byte{97,98,99})
    fmt.Printf("str=%v\n", str1)

    // 10进制转2
    str2 := strconv.FormatInt(123, 2)
    fmt.Println("formatInt2: ", str2)

    // 10进制转16
    str3 := strconv.FormatInt(123, 16)
    fmt.Println("formatInt16: ", str3)

    // 在字符串中是否存在子串
    is := strings.Contains("seafood", "foo")
    fmt.Println("strings.Contains: ", is)

    // 不区分大小写的字符串比较
    fmt.Println(strings.EqualFold("abc", "Abc"))

    // 区分大小写比较
    fmt.Println("abc" == "Abc")

    // 返回子串第一次出现的index值
    // LastIndex最后一次出现
    fmt.Println(strings.Index("LNT_abc", "abc"))

    str4 := strings.Replace("go go hello", "go", "go语言", -1)
    fmt.Println("Replace: " + str4)

    //fmt.Println(strconv.IntSize)
    }

    文件操作

    • os.File封装所有文件操作,是一个结构体
    • bufio.Reader和bufio.Writer包含缓冲的读写,都是一个结构体
    • io/ioutil可以一次性将整个文件读到内存中,适合文件不大的情况

    读文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    package main

    import (
    "fmt"
    "os"
    )

    func read_file(filename string) {
    // fin是一个*File
    fin, err := os.Open(filename)

    if err != nil {
    fmt.Println(err)
    return
    }
    defer fin.Close()

    buf := make([]byte, 1024)

    for {
    n, _ := fin.Read(buf)

    // 0表示到达EOF
    if n == 0 {
    break
    }

    os.Stdout.Write(buf)
    }

    }

    func main() {
    read_file("./aa.txt")

    }

    写文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    package main

    import (
    "fmt"
    "os"
    )

    func main() {
    myFile := "./aa.txt"
    fout, err := os.Create(myFile)

    if err != nil {
    fmt.Println(err)
    return
    }

    for i := 0; i < 10; i++ {
    outStr := fmt.Sprintf("%s:%d\n", "Hello", i)

    fout.WriteString(outStr)
    fout.Write([]byte("abcd\n"))
    }

    fout.Close()

    }

    读时写

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    package main

    import (
    "fmt"
    "io"
    "os"
    )

    func main() {
    fi, err := os.Open("./aa.txt")
    if err != nil {
    fmt.Println(err)
    }
    defer fi.Close()

    fo, err := os.Create("./aa_new.txt")
    if err != nil {
    fmt.Println(err)
    }
    defer fo.Close()

    buf := make([]byte, 1024)

    for {
    n, err := fi.Read(buf)
    if err != nil && err != io.EOF {
    fmt.Println(err)
    }
    if n == 0 {
    break
    }

    if n2, err := fo.Write(buf[:n]); err != nil {
    panic(err)
    } else if n2 != n {
    panic("error in writing")
    }
    }
    }

    用bufio库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    package main

    import (
    "os"
    "bufio"
    )

    func main() {

    file, err := os.OpenFile("./test.txt", os.O_CREATE | os.O_WRONLY, 0666)
    if err != nil {
    panic(err)
    }

    defer file.Close()

    w := bufio.NewWriter(file)

    for i := 0; i < 5; i++ {
    w.WriteString("hello\n")
    }

    // 数据是先写到缓冲区的,此处刷新才到文件中
    w.Flush()
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    package main

    import (
    "bufio"
    "io"
    "os"
    )

    func main() {
    fi, err := os.Open("./aa.txt")
    if err != nil {
    panic(err)
    }
    defer fi.Close()
    r := bufio.NewReader(fi)

    fo, err := os.Create("./aa1.txt")
    if err != nil {
    panic(err)
    }
    defer fo.Close()
    w := bufio.NewWriter(fo)

    buf := make([]byte, 1024)

    for {
    n, err := r.Read(buf)
    if err != nil && err != io.EOF {
    panic(err)
    }
    if n == 0 {
    break
    }

    if n2, err := w.Write(buf[:n]); err != nil {
    panic(err)
    } else if n2 != n {
    panic("error in writing")
    }
    }

    if err = w.Flush(); err != nil {
    panic(err)
    }
    }

    用ioutil库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package main

    import (
    "io/ioutil"
    )

    func main() {
    b, err := ioutil.ReadFile("./aa.txt")
    if err != nil {
    panic(err)
    }

    err = ioutil.WriteFile("./aa2.txt", b, 0644)
    if err != nil {
    panic(err)
    }
    }

    判断文件是否存在

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    func PathExists(path string)(boo, error) {
    _, err := os.Stat(path)
    if err == nil { // 获取path的信息成功,说明路径存在
    return true, nil
    }
    if os.IsNotExist(err) {
    return false, nil
    }
    return false, err

    }

    JSON操作

    编码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    package main

    import (
    "encoding/json"
    "fmt"
    "log"
    )

    type Moive struct {
    Title string
    Year int `json:"released"` // Tag元信息,编码时重命名key
    Color bool `json:"color,omitempty"` // omitempty表示结构体成员为空或零值时不生成该JSON对象
    Actors []string
    }

    var movies = []Moive{
    {Title: "战狼2", Year: 2017, Color: true, Actors: []string{"吴京", "吴刚"}},
    {Title: "老炮儿", Year: 2015, Color: true, Actors: []string{"冯小刚", "吴亦凡", "许晴"}},
    {Title: "Bullitt", Year: 1968, Color: false, Actors: []string{"Steve McQueen", "Jacqueline Bi sset"}},
    }

    func main() {
    // json紧凑格式

    //json_str, err := json.Marshal(movies)

    // 格式化的json,后两参数表示每一行输出的前缀和每一个层级的缩进
    json_str, err := json.MarshalIndent(movies, "", " ")
    if err != nil {
    log.Fatal(err)
    return
    }

    fmt.Printf("%s\n", json_str)
    }

    解码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    package main

    import (
    "encoding/json"
    "fmt"
    "log"
    )

    type Moive struct {
    Title string
    Year int `json:"released"` // Tag元信息,编码时重命名key
    Color bool `json:"color,omitempty"` // omitempty表示结构体成员为空或零值时不生成该JSON对象
    Actors []string
    }

    var movies = []Moive{
    {Title: "战狼2", Year: 2017, Color: true, Actors: []string{"吴京", "吴刚"}},
    {Title: "老炮儿", Year: 2015, Color: true, Actors: []string{"冯小刚", "吴亦凡", "许晴"}},
    {Title: "Bullitt", Year: 1968, Color: false, Actors: []string{"Steve McQueen", "Jacqueline Bi sset"}},
    }

    func main() {
    // json紧凑格式
    json_str, err := json.Marshal(movies)

    // 格式化的json,后两参数表示每一行输出的前缀和每一个层级的缩进
    // json_str, err := json.MarshalIndent(movies, "", " ")
    if err != nil {
    log.Fatal(err)
    return
    }

    fmt.Printf("%s\n", json_str)

    fmt.Println("-----------------")

    var titles []struct {
    Title string
    }
    if err := json.Unmarshal(json_str, &titles); err != nil {
    log.Fatal(err)
    return
    }
    fmt.Printf("Titles: %+v\n", titles)

    /* 注意 json 编解码 只能处理结构体成员变量是大写的字段,小写的直接忽略
    如果在编码时, 想让json字符串的字段小写,那么需要再结构体中加Tag
    如果再解码时, json有小写的字段名,那么在定义结构体接收的时候,成员名要大写,然后也要加Tag */
    var my_movies []struct {
    Title string
    Year int `json:"released"`
    Actors []string
    }
    if err := json.Unmarshal(json_str, &my_movies); err != nil {
    log.Fatal(err)
    return
    }

    fmt.Printf("movies: %+v\n", movies)
    }

    解析命令行参数

    os.Args

    1
    var Args []string // 切片

    存储所有命令行参数,第0个是程序名

    flag包

    os.Args对解析cmd> main.exe -f c:/aa.txt -p 200 -u root 这样的命令行参数不太方便

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    package main

    import (
    "flag"
    "fmt"
    )

    func main() {

    // 用于接受命令行参数
    var host string
    var port int

    flag.StringVar(&host, "h", "localhost", "主机名,默认localhost")
    flag.IntVar(&port, "p", 8080, "端口号,默认8080")

    // 解析
    flag.Parse()
    fmt.Printf("host: %v, port: %v\n", host, port)

    }

    单元测试

    • 测试用例文件必须以_test.go结尾
    • 测试用例函数必须以Test开头,且形参必须是t *testing.T
    1
    2
    3
    4
    go test // 如果正确无日志,错误会有
    go test -v // 正确与否,都会有错误日志
    go test -v cal_test.go cal.go // 测试单个文件,要带上被测试的原文件
    go test -v -test.run TestAddUser // 测试单个方法
    • 出错时,可用t.Fatalf来格式化输出错误

    • t.Logf方法可以输出日志

    参考资料