第1节-基础语法-学习笔记| 青训营笔记

194 阅读6分钟

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

前言

这篇文章包括以后的青训营系列文章都是记录我在青训营上课学习所记录的笔记。
这是一个go零基础的小白同学的记录,内容不局限于老师上课所讲,还因为基础较差,所以我记录的还有比老师上课更基础的内容,还包括我遇到的问题去网络收集的结果,既是对自己学习的记录,也希望对同样是零基础的同学有点帮助吧。

基础语法

1、创建变量

var name string = "yuming" //var+变量名+变量类型
var name = "yuming"   //可省略变量类型
var (   //多个变量一起声明
    name string
    age int
    gender string
)
name := "yuming" //使用 `:=` (推导声明写法),这样可省略变量类型和var

2、匿名变量

匿名变量,也称作占位符,用下划线表示。 通常我们用匿名接收必须接收,但是又不会用到的值。

a, _ := func1() // 这里的_就是匿名变量,函数返回两个变量,但是第二个变量用不到就用匿名变量接受

3、字符串

字符串基本常识

Go 语言的 string 是用 uft-8 进行编码的,英文字母占用一个字节,而中文字母占用 3个字节 字符串可以用双引号和反引号表示,反引号不转义,反引号也可以表示多行的字符串 var mystr01 string = 你好呀! 我叫yuming
等价于
var mystr01 string = “你好呀!\n我叫yuming”

Strigns的基本操作(源于老师内容)

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个字节,使用utf-8编码

4、数组

//声明数组
var arr [3]int
// 声明数组并初始化
arr := [3]int{1,2,3}
// 声明动态数组
arr := [...]int{1,2,3}

可以给数组定义别名 type arr3 [3]int
数组不常用,更常用的是切片

5、切片

// 声明切片
var ming []int
// 声明并初始化
s := []int{2, 3, 5, 7, 11, 13}

切片类型打印出来是:[]int,而数组类型打印出来含有数字,例如[2]int。

切片是引用类型,所以你不对它进行赋值的话,它的零值(默认值)是 nil

切片是对数组的一个连续片段的引用,左闭右开的区间

切片的一些相关方法

len(x),cap(x) //求切片的长度和容量
ming = append(ming, 2,3,4) //往切片添加多个元素
/* 创建切片 mingming 是之前切片的两倍容量*/
mingming := make([]int, len(ming), (cap(ming))*2)

切片的本质

切片本质是一个底层数组+start指针+end指针 start指针就是指针底层数组的首地址,所以start指针往后移动的话,底层数组也会变小,丢失前面的数据。而end往后移动时,底层数组不会变化,只是切片的长度变长。 综上,切片的容量就是底层数组的大小,切片的大小就是end-start的大小。 即:

len=end-start
cap=cap-start

6、字典

三种声明并初始化字典的方法

// 第一种方法
var scores map[string]int = map[string]int{"english": 80, "chinese": 85}
// 第二种方法
scores := map[string]int{"english": 80, "chinese": 85}
// 第三种方法
scores := make(map[string]int)
scores["english"] = 80
scores["chinese"] = 85

最常用的是第三种

字典基本操作

scores["math"] = 95  //添加
scores["math"] = 100 //更新
scores["math"] //读取
delete(scores, "math")//删除
scores["english"] // 访问不存在的key 会返回这个值的零值
math, ok := scores["math"] //字典读取可以返回两个值,第二个值表示key是否存在

遍历

//方式1:获取 key 和 value
for subject, score := range scores {
        fmt.Printf("key: %s, value: %d\n", subject, score)
    }
//方式2:只获取key,这里注意不用占用符。
 for subject := range scores {
        fmt.Printf("key: %s\n", subject)
    }
//方式3:只获取 value,用一个占位符替代。
for _, score := range scores {
        fmt.Printf("value: %d\n", score)
    }

7、布尔类型

go中true与1不相等

Go 语言中,则使用 && 表示,用 || 表示,并且有短路行为(即左边表达式已经可以确认整个表达式的值,那么右边将不会再被求值。

流程控制方法

1、if-else

在 if 里可以允许先运行一个表达式,取得变量后,再对其进行判断(类似for循环)

 if age := 20;age > 18 {
        fmt.Println("你是大人了")
    }

2、switch-case

case 后可以接多个多个条件,多个条件之间是 的关系,用逗号相隔。

import "fmt"
func main() {
    month := 2
    switch month {
    case 3, 4, 5:
        fmt.Println("这是属于春天呀")
    case 6, 7, 8:
        fmt.Println("这是属于夏天呀")
    case 9, 10, 11:
        fmt.Println("这是属于秋天呀")
    case 12, 1, 2:
        fmt.Println("这是属于冬天呀")
    default:
        fmt.Println("请输入1-12月份哦...")
    }
}

3、for循环

最常用的是for循环,go没有while循环,用法如下:

1、接一个条件表达式,类似while( a <= 5 ){}

for a <= 5 {
    fmt.Println(a)
    a ++
}

2、接三个表达式

  for i := 1; i <= 5; i++ {
        fmt.Println(i)
    }

3、不接表达式:无限循环,类似while(true){}

for{ }

4、接 for-range 语句

range 后可接数组、切片,字符串等, range 会返回两个值:索引和数据,如果后面的代码用不到索引,需要使用 _ 表示

myarr := [...]string{"world", "python", "go"}
    for _, item := range myarr {
        fmt.Printf("hello, %s\n", item)
    }

如果用一个变量来接收的话,接收到的是索引

4、defer 延迟语句

defer 的用法很简单,只要在后面跟一个函数的调用,就能实现将这个函数的调用延迟到当前函数执行完后再执行。

使用 defer 只是延时调用函数。即变量已经在此刻传进去了,但是还没执行函数,后面变量改变不影响

name := "go"
defer fmt.Println(name) // 输出: go
name = "python" //改变变量不影响defer的函数的输入参数是go
fmt.Println(name)      // 输出: python

多个defer 是反序调用的,有点类似栈一样,后进先出。

defer 是return 后才调用的

defer用法:释放资源 不用在每个return前都写一句释放资源,而是写一句defer修饰的释放资源,都会在return之后执行

异常处理

errors新建异常

errors.New("not found")

panic手动抛出异常

panic("crash")

recover 捕获异常

        // recover() 可以将捕获到的panic信息打印
        if err := recover(); err != nil {
            fmt.Println(err)
        }

总结

因为第一次写博客,也不太会写,写得也不算生动,见谅。其实这更多的算是一种自我的记录,记录自己不会的知识点,并上网查询,总结到文章里,以防止忘记了快速浏览捡起。原谅我的自私。不过记录下自己每天进步一点点的足迹,其实也是一件很令人开心的事呢!!!