Go语言基础及安装|青训营笔记

81 阅读6分钟

这是我参与「第五届青训营 」笔记创作活动的第1天

一、本堂课重点内容:

本节课介绍了go语言的优势、开发环境、基础语法和标准库,并通过三个案例巩固知识

二、详细知识点介绍:

1. go语言优势:

  • 高性能、高并发
  • 语法简单、学习曲线平缓
  • 标准库丰富
  • 工具链完善
  • 静态链接
  • 快速编译
  • 跨平台
  • 垃圾回收

2. 工具

3. 基础语法

3.1 变量

3.1.1定义变量
  • 格式:var identifier typename
  • 例子:var num int =10
  • 格式:typename := value
  • 例子:
var num int
num=10
num2:=10
  • 如果没有赋值则为系统默认值
类型默认值
数值型0
布尔型false
字符串“”
3.1.2多全局变量声明
  • 格式:var ( vname1 v_type1 vname2 v_type2 )
  • 例子:
var{
a int
b int
}

3.2if else

格式:

if 表达式{

}else if 表达式{

}else{

}

3.3循环

形式语法
和c语言中的for相同for init; condition; post {}
和c语言中的while相同for condition{}
和c语言中的for(;;)相同for{}

3.4switch

Switch v{
case var1:
    ...
case var2:
    ...
default:
    ...
}

其中的变量v可以是任何类型,var1var2可以是同类型的任意值,类型不局限为常量或者整数,或者最终结果为相同类型的表达式。

3.5数组

3.5.1声明数组
  • 格式:var variable_name [SIZE] variable_type
  • 例子:var num [10] int
3.5.2初始化数组
方法格式
直接赋值 var num=[10]int{0,0,0,...}
通过字面量num:=[10]int{0,0,0,...}
数组长度不确定var num=[...]int{0,0}num:=[...]int{0,0}
指定下标进行部分初始化num:=[10]int{1:1,5:10}

3.6切片

3.6.1添加元素
函数位置例子
append()在切片尾部添加num=append(num,3)
在切片头部添加num=append([]int{0},num)
3.6.2删除元素
位置方法例子(删除相应位置的N个数)
从开头删除直接移动数据指针num=num[N:]
将后面的数据向开头移动num= append(num[:0], num[N:]...)
使用copy将后续数据向前移动num= num[:copy(num,num[N:])]
从中间位置删除append()num = append(num[:i], num[i+N:], ...)
copy()num=num[:copy(a[:i], a[i+N:])]
从尾部删除直接删除num = num[:len(num)-N]

补充:make函数(分配内存)

  • 语法结构:make(type,len,cap)
  • 例子:
s:=make([]string,3)
s[0]="s"//len为数组的长度,cap=0,cap是底层数组的大小
  • 容量的用处在哪?
  • 原理:当append扩展长度时,如果新的长度小于容量,不会更换底层数组,否则,go 会新申请一个底层数组,拷贝这边的值过去,把原来的数组丢掉。
  • 用途:在数据拷贝和内存申请的消耗与内存占用之间提供一个权衡。

3.7map

3.7.1初始化map:
//way1:
	m1 := make(map[string]string)
	m1["age"] = "10"
	m1["name"] = "gufei"
//way2:
        m2 = map[string]string{"age": "10", "name": "gufei"}
3.7.2插入数据

格式:map_variable["age"] = 10

3.7.3删除数据

格式: delete(map_variable,"age")

特点如下:

  • map是无序的(原因为无序写入以及扩容导致的元素顺序发生变化),每次打印出来的map都会不一样,它不能通过index获取,而必须通过key获取

  • map的长度是不固定的,是一种引用类型(和slice一样)

  • 可使用内置len函数,返回map拥有的key的数量

  • map的key可以是所有可比较的类型,如布尔型、字符串型、键等。

3.8range

3.8.1遍历数组

格式:

myArray := [3]int{1, 2, 3}
for i, ele := range myArray {
    fmt.Printf("index:%d,element:%d\n", i, ele)
    fmt.Printf("index:%d,element:%d\n", i, myArray[i])
}

image.png

3.8.2遍历slice
mySlice := []string{"I", "am", "a","girl"}
for i, ele := range mySlice {
    fmt.Printf("index:%d,element:%s\n", i, ele)
    fmt.Printf("index:%d,element:%s\n", i, mySlice[i])
}
3.8.3遍历字符串
s:="gufei"
for i,ele := range s {
   fmt.Println(string(ele))
   fmt.Printf("index:%d,element:%s\n", i, string(s[i]))
}
3.8.4遍历map
myMap := map[int]string{1:"语文",2:"数学",3:"英语"}
for key,value := range myMap {
    fmt.Printf("key:%d,value:%s\n", key, value)
    fmt.Printf("key:%d,value:%s\n", key, myMap[key])
}

3.9函数

格式:

func fuction_name([parameter list])(return types){
	函数体
}

例子:

func add(a int,b int)int{
return a+b
}
func exists(m map[string]string ,k string)(v string,ok bool){
v,ok = m[k]
return v,ok
}

3.10指针

例子:

func add(n *int){
*n+=2
}
func main(){
n:=5
add(&n)
}

3.11结构体

3.11.1声明结构体

格式:

//way1:
type struct_variable_type struct {
   member definition
   member definition
   ...
   member definition
}
//例子:
type user struct{
name string
password string
}

//way2:
variable_name := structure_variable_type {value1, value2...valuen}

variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}
//例子:
a=user{"wang","1234"}
b:=user{name:"wang",password:"1234"}
3.11.2访问结构体成员
  • 格式: 结构体变量名.成员名
  • 例子:

image.png

3.12结构体方法

例如:

image.png

3.13错误处理

  • 习惯用函数的返回值来处理错误信息,可在函数返回值里加err,如果出现错误可以用errors.new去创建。
  • 例如:
func findUsers(users []user,name string )(v *user,err error){
    for i,u:=range users{
    if u.name==name{
        return &u,nil
        }
    }
    return nil,errors.New("not found") 
}

3.14字符串操作

字符串标准库里有多个工具函数如:

a := "hello"
fmt.Println(strings.Contains(a, "ll"))                // true
fmt.Println(strings.Count(a, "l"))                    // 2
fmt.Println(strings.HasPrefix(a, "he"))               // true
fmt.Println(strings.HasSuffix(a, "llo"))              // true
fmt.Println(strings.Index(a, "ll"))                   // 2
fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo
fmt.Println(strings.Repeat(a, 2))                     // hellohello
fmt.Println(strings.Replace(a, "e", "E", -1))         // hEllo
fmt.Println(strings.Split("a-b-c", "-"))              // [a b c]
fmt.Println(strings.ToLower(a))                       // hello
fmt.Println(strings.ToUpper(a))                       // HELLO
fmt.Println(len(a))                                   // 5
b := "你好"
fmt.Println(len(b)) // 6

3.15字符串格式化

在go语言中可用%v处理任意类型的变量,用%+v可更加详细(增加变量名的信息),用%#v会进一步详细(还增加调用的函数信息)

例如:

s := "hello"
n := 123
p := point{1, 2}
fmt.Println(s, n) // hello 123
fmt.Println(p)    // {1 2}
fmt.Printf("s=%v\n", s)  // s=hello
fmt.Printf("n=%v\n", n)  // n=123
fmt.Printf("p=%v\n", p)  // p={1 2}
fmt.Printf("p=%+v\n", p) // p={x:1 y:2}
fmt.Printf("p=%#v\n", p) // p=main.point{x:1, y:2}

3.16json处理("encoding/json"包)

对于一个已有的结构体,只要保证每个字段的第一个字母是大写(若要字母小写,在构造结构体时可在变量后面写 json:"小写的变量名"),可通过json.Marshal去序列化,打印的时候需要加string强制类型转换为字符串,否则会打印出一些十六进制的编码 例如:

type userInfo struct {
   Name  string
   Age   int `json:"age"`
   Hobby []string
}

func main() {
   a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
   buf, err := json.Marshal(a)
   if err != nil {
      panic(err)
   }
   fmt.Println(buf)         // [123 34 78 97...]
   fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}

当然也可以通过json.Unmarshal去反序列化赋值到空的变量里.

例如:

var b userInfo
err = json.Unmarshal(buf, &b)
fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}

3.17时间处理("time"包)

  • time.Now():快速获取当前时间
  • t:=time.Date(年,月...):构造一个带时区的时间,可利用t.Year(),t.Month()等方式可以获取该时间点的信息
  • t.Format()或者time.Parse():解析时间
  • time.Unix():获取时间戳

3.18数字解析("strconv"包)

  • strconv.ParseFloat()或strconv.ParseInt(字符串,进制,精度):解析字符串
  • strconv.Atoi():将十进制字符串转成数字
  • strconv.Itoa():将数字转成字符串

3.19进程信息

  • os.Args:获取进程在执行时的一些命令行参数
  • os.Getenv()或者os.Setenv():获取或者写入环境变量