青训营第一节课程-基础语言 复习|青训营笔记

132 阅读5分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记

本文将介绍往期基础知识的回顾。

一、错误处理

Golang的错误处理通过返回值的设计,强迫调用者对错误进行处理,要么处理要么忽略。因此,在golang当中我们经常会大量使用if来对错误处理进行判定。

func main() {
    conent,err:=ioutil.ReadFile("filepath")
    if err !=nil{
        //错误处理
    }else {
        fmt.Println(string(conent))
    }
}

通常err是nil的,此时表示没有任何错误。但是非nil的时候就表示会出现错误,我们需要进行处理。

二、字符串操作

Contains()函数

Contains() 函数返回 bool 类型的值,如果包含,则返回 true;反之,则返回 false。

package main


import (
	"fmt"
	"strings"
)

func main() {

	//使用 Strings.Contains() 函数,判断一个字符串是否在另一个字符串中
	strHaiCoder := "字节(HaiCoder)"
	StrContainers := strings.Contains(strHaiCoder, "HaiCoder")
	fmt.Println("StrContainers =", StrContainers)
}

Strings.count()函数

函数返回 int 类型的值,如果检索的字符串不存在,则返回 0,否则返回出现的次数。

package main
import (
	"fmt"
	"strings"
)
func main() {

	//使用 Strings.count() 函数,统计字符串中单个字符出现的次数
	strHaiCoder := "Study Golang From HaiCoder"
	count := strings.Count(strHaiCoder, "o")
	fmt.Println("count =", count)
}

Strings.HasPrefix()函数

用于检索字符串是否以指定字符串开头,如果是返回 True;反之返回 False。

package main
import (
    "fmt"
    "strings"
)
func main() {

	//使用 strings.HasPrefix() 函数,判断以指定字符串开始,返回 True
	strHaiCoder := "I study Golang From HaiCoder"
	prefix := strings.HasPrefix(strHaiCoder, "I study")
	fmt.Println("prefix =", prefix)
}

index()函数

Index() 函数返回 int 类型的值,如果包含,则返回第一次出现该字符串的索引;反之,则返回 -1。

package main
import (
	"fmt"
	"strings"
)
func main() {

	//使用 Strings.Index() 函数,统计字符串某个字符第一次出现的位置
	strHaiCoder := "I love Golang and I study Golang From HaiCoder"
	index := strings.Index(strHaiCoder, "l")
	fmt.Println("index =", index)
}

Json

Json(Javascript Object Nanotation)是一种数据交换格式,常用于前后端数据传输。任意一端将数据转换成json 字符串,另一端再将该字符串解析成相应的数据结构,如string类型,strcut对象等。

Json Marshal:将数据编码成json字符串

type Stu struct {
    Name  string `json:"name"`
    Age   int
    HIgh  bool
    sex   string
    Class *Class `json:"class"`
}

type Class struct {
    Name  string
    Grade int
}

func main() {
    //实例化一个数据结构,用于生成json字符串
    stu := Stu{
        Name: "张三",
        Age:  18,
        HIgh: true,
        sex:  "男",
    }

    //指针变量
    cla := new(Class)
    cla.Name = "1班"
    cla.Grade = 3
    stu.Class=cla

    //Marshal失败时err!=nil
    jsonStu, err := json.Marshal(stu)
    if err != nil {
        fmt.Println("生成json字符串错误")
    }

    //jsonStu是[]byte类型,转化成string类型便于查看
    fmt.Println(string(jsonStu))
}

结果:
{"name":"张三","Age":18,"HIgh":true,"class":{"Name":"1班","Grade":3}}

从结果中可以看出

  • 只要是可导出成员(变量首字母大写),都可以转成json。因成员变量sex是不可导出的,故无法转成json。
  • 如果变量打上了json标签,如Name旁边的 json:"name" ,那么转化成的json key就用该标签“name”,否则取变量名作为key,如“Age”,“HIgh”。
  • bool类型也是可以直接转换为json的value值。Channel, complex 以及函数不能被编码json字符串。当然,循环的数据结构也不行,它会导致marshal陷入死循环。
  • 指针变量,编码时自动转换为它所指向的值,如cla变量。
  • (当然,不传指针,Stu struct的成员Class如果换成Class struct类型,效果也是一模一样的。只不过指针更快,且能节省内存空间。)
  • 最后,强调一句:json编码成字符串后就是纯粹的字符串了。

Json Unmarshal

Unmarshal函数解析json编码的数据并将结果存入v指向的值。

Unmarshal和Marshal做相反的操作,必要时申请映射、切片或指针

package main

import (
	"encoding/json"
	"fmt"
)

// Actress 女演员
type Actress struct {
	Name       string
	Birthday   string
	BirthPlace string
	Opus       []string
}

func main() {

	// 普通JSON
	// 因为json.UnMarshal() 函数接收的参数是字节切片,   // 所以需要把JSON字符串转换成字节切片。
	jsonData := []byte(`{
      "name":"迪丽热巴",
      "birthday":"1992-06-03",
      "birthPlace":"新疆乌鲁木齐市",
      "opus":[
         "《阿娜尔罕》",
         "《逆光之恋》",
         "《克拉恋人》"
      ]
   }`)

	var actress Actress
	err := json.Unmarshal(jsonData, &actress)
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Printf("姓名:%s\n", actress.Name)
	fmt.Printf("生日:%s\n", actress.Birthday)
	fmt.Printf("出生地:%s\n", actress.BirthPlace)
	fmt.Println("作品:")
	for _, val := range actress.Opus {
		fmt.Println("\t", val)
	}
}

时间处理

时间戳
time.Now().Unix()

时间格式化
time.Now().Format("2006-01-02 15:04:05")

时间点必须为2006-01-02 15:04:05, go语言诞生之日



时间戳转字符串格式化时间
str_time := time.Unix(1389058332, 0).Format("2006-01-02 15:04:05")
fmt.Println(str_time)


字符串格式化时间转时间戳
the_time, err := time.Parse("2006-01-02 15:04:05", "2014-01-08 09:04:41")
if err == nil {
    unix_time := the_time.Unix()
	fmt.Println(unix_time)		
}


检查两个时间对象是否在同一日期
func DateEqual(t1 time.Time, t2 time.Time) bool {
	y1, m1, d1 := t1.Date()
	y2, m2, d2 := t2.Date()
	return y1 == y2 && m1 == m2 && d1 == d2
}

func DateEqual(date1, date2 time.Time) bool {
    return date1.Format("20060102") == date2.Format("20060102")
}

猜谜游戏代码解析

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"time"
)

func main() {
	maxNum := 100
	rand.Seed(time.Now().UnixNano())
	secretNumber := rand.Intn(maxNum) // rand.Intn是伪随机数 rand.Intn () 函数是个伪随机函数,不管运行多少次都只会返回同样的随机数。
	//因为它默认的资源就是单一值,所以必须调用 rand.Seed (), 并且传入一个变化的值作为参数,如 time.Now().UnixNano() , 就是可以生成时刻变化的值.
	// fmt.Println("The secret number is ", secretNumber)

	fmt.Println("Please input your guess")
	reader := bufio.NewReader(os.Stdin) //读入你输入的数字
	for {
		input, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("An error occured while reading input. Please try again", err)
			continue
		}
		input = strings.TrimSuffix(input, "\n") //去除字符串后缀函数

		guess, err := strconv.Atoi(input) //字符类型转化为int类型
		if err != nil {
			fmt.Println("Invalid input. Please enter an integer value")
			continue
		}
		fmt.Println("You guess is", guess)
		if guess > secretNumber {
			fmt.Println("Your guess is bigger than the secret number. Please try again")
		} else if guess < secretNumber {
			fmt.Println("Your guess is smaller than the secret number. Please try again")
		} else {
			fmt.Println("Correct, you Legend!")
			break
		}
	}
}

`