zero day 2021-11-21

golang 中,defer的执行顺序类似栈,先进后出。当出现panic的时候,会先执行defer 最后才会执行panic。

first day 2021-11-22

for range 循环的时候会创建每个元素的副本,而不是元素的引用。

second day 2021-11-23

  1. append函数可像切片中追加数据,之前的数据也会保留
  2. 函数有多个返回值时,只要有一个返回值有明明,其他的也必须命名,如果有多个返回值,则必须加上括号;另外只要有返回值命名无论数量多少,都需要加括号
  3. new() make() 都用来分配内存;
    new()用于为值类型分配内存,如 数组、结构体等; make()用于为引 用类型分配内存,如 切片(slice),集合(map) ,管道(channel)。
    引用类型:指针,slice切片,map,管道chan,interface等都是引用数据类型;
    值类型: 基本数据类型int系列,float系列,bool,string,数组和结构体 struct;
    引用类型特点: 变量存储的是一个地址,内存通常在堆上分配;
    值类型特点: 变量直接存储值,内存通常在栈中分配。

third day 2021-11-24

  1. 值类型使用 new来分配空间,引用类型使用make来分配空间。以目前的经验来看,new有一个参数,该参数需要传递数据类型,并返回指向数据类型的指针,make可有多个参数,第一个参数是值的类型,之后的参数是整型的变量,并返回分配的类型,这里有点不解,为什么new返回类型的指针,但是却被提倡为值类型分配空间,而make返回的是类型,却被体长为引用类型分配空间?
  2. append函数的使用,第二个参数是切片时,需在参数后加…
  3. := 这种声明方式有一些限制
    1. 必须使用显示初始化;
    2. 不能提供数据类型,编译器会自动推导;
    3. 只能在函数内部使用简短模式。

fourth day 2021-11-25

结构体的比较:
1. 结构体只能比较是否相等,不能比较大小
2. 相同类型的结构体才可以进行比较,结构体是否相同不但与属性类型有关, 还与属性顺序相关。此外 常见可比较的类型有: bool、数值型、字符、指针、数组。
不可比较的类型有:切片、map、函数等。
3. golang是强类型语言
强类型语言:一旦一个变量被定义为某个数据类型,如果不强制转换类型,那么它一直是被定义的类型。
弱类型语言:一个变量可以被赋于不同数据类型的值。

fifth day 2021-11-26

itoa 用法:

  1. 每次const 出现时,都会让iota 初始化为0
  2. 在const中可使用 _ 跳过值
  3. 位掩码表达式(移位操作的自增)
    nil赋值:
    nil只能赋值给指针、chan、func、 interface、map、slice 、error

init函数注意点:

  1. init函数是用于程序执行前做包的初始化的函数
  2. 一个包可以有多个init函数,但是执行顺序没有明确定义,但是不同包的init函数是根据包导入的依赖关系决定的
  3. init函数不能被显示的使用
  4. 被多次引用的包只会初始化一次
  5. 死循环似的引入包,不被允许。

类型选择:
只有接口可以进行类型选择:
var i interface{}
i.(type)

sixthday 20211127

  1. 写channel必须带上值

seventhday 20211128

  1. golang是强类型语言,不制支持类型自动转换。
  2. 截取切片操作符的知识点:操作符[i,j]。基于数组(切片)可以使用操作符[i,j]创建新的切片,从索引 i ,到索引 j 结束,截取已有数组(切片)的任意部分,返回新的切片, 新切片的值包含原数组(切片)的 i 索引的值, 但是不包含 j 索引的值。 i, j 都是可选的,i如果省略,默认是0 , j如果省略, 默认是原数组(切片)的长度。 i , j都不能超过这个长度值。
    假如底层数组的大小为k,截取之后获得的切片的长度和容量的计算方法:长度:j - i ,容量: k - i
    截取操作符还可以有第三个参数,形如[i, j, k], 第三个参数k 用来限制新切片的容量,但不能超过原数组(切片)的底层数组大小。截取获得的切片的长度和容量分别是: j - i,k - i。
  3. cap函数 不能用于求 map的容量。
  4. 仅当接口的动态值和动态类型都为nil 时, 接口类型值才为nil
  5. 集合操作,删除map中不存在的键值对时,不会报错,相当于没有任何作用。

ninthday 20211129

  1. golang有25个关键字
  2. 结构体嵌套:在嵌套结构体中, People称为内部类型, Teacher称为外部类型;通过嵌套,内部类型的属性、方法,可以为外部类型所有,就好像是外部类型自己的一样。此外,外部类型还可以定义自己的属性和方法,甚至可以定义与内部相同的方法,这样内部类型的方法就会被“屏蔽”。

tenthday 20211130

  1. *符号优先级在 ++ 之后
  2. 可变函数传参,后面要带有…
  3. nil切片和nil相等,一般用来表示一个不存在的切片;空切片和nil不相等,表示一个空的集合。
  4. 一定要注意,map 的声明是没有被赋值空间的,只有使用make采行。当key的元素不存在时,int型会返回零值,并返回false。
  5. 静态类型(static type),就是变量生命的时候的类型
  6. 动态类型(concrete type, 也叫具体类型)是程序运行时系统才能看见的类型。

eleventh 20211201

  1. defer 具名函数 匿名函数
    defer 调用具名函数时,如果该具名函数的某个参数引用了另外一个函数,则defer语句在注册的时候就会执行函数B() 但是函数A()的执行则延迟到defer外围函数即将退出时。
    如果defer语句调用的是一个匿名函数,那么匿名函数体内不管有什么复杂的逻辑,统统在defer外围函数即将退出时才执行。
  2. 类型断言
  3. defer、return 、返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入返回值中,接着defer开始执行一些收尾工作;最后函数携带当前返回值退出。

twelfthday 20211202

  1. defer 后面跟非函数性语句时,会先压栈,并把变量备份。
  2. 切片声明,优先选择不分配内存的声明方式。
  3. 永远不要使用一个指针指向一个接口类型,因为它已经是一个指针。

thirteenthday 20211203

  1. golang 的字符串类型是不能赋值nil的,也不能跟nil比较
  2. defer关键字后面的函数或者方法要想执行必须先注册, return之后的defer是不能注册的,也就不能执行后面的函数或方法。

fourteenthday 20211204

  1. golang 中切片底层的数据结构是数组。当使用s1[1:]获得切片s2, 和s1共享一个底层数组,s2中的值变化时,s1的值也变化。但是append操作会导致底层数组扩容,生成新数组,因此追加数据后,在改变s2,不会影响s1。
  2. map的输出是无序的。
  3. 基于类型创建的方法必须定义在同一个包内。

fiveteenthday 20211205

  1. itoa 在const关键字出现时将被重置为0, const中每新增一行常量声明将使iota计数一次
  2. 如果类型重新定义了String()方法,当使用fmt.Prinf()、fmt.Print() 和 fmt.Println()会自动使用String()方法,实现字符串的打印。

sixteenthday 20211206

  1. go 中不同类型不能比较,切片不能比较。
  2. golang中,吐过新变量与同名一定义的变量不在同一个作用域中,那么Go会新定义这个变量。
  3. 循环次数在循环开始前就已经确定。
  4. golang中闭包是引用了自由变量的函数,被引用的自耦变量和函数一同存在,即使已经离开了自由变量的环境也不会被释放或删除,在比保重可以继续使用这个自由变量,因此:闭包= 函数+引用环境。闭包里的非传递参数外部变量值是传引用的。

seventeenthday 20211208

  1. range表达式时副本参与循环。
  2. 切片在go的内部结构有一给指向底层数组的指针,当range表达式发生复制时,副本的指针依旧指向原底层数组,所以对切片的修改都会反映到底层数组上。

eighteenthday 20211209

  1. for 循环不支持以逗号为间隔的多个赋值语句,必须使用平行赋值的方式来初始化多个变量。
  2. 多重赋值分为两个步骤,有先后顺序:
    1. 计算等号左边的索引表达式和取址表达式,接着计算等号右边的表达式;
    2. 赋值

nineteenthday 20211212

  1. 关于switch语句,单个case中,可以出现多个结果选项
  2. 自增自减操作。i++和i-- 在Go语言中是语句,不是表达式,因此不能赋值给另外的变量,此外,没有++i --i

twentieth 20211215

  1. 实现接口所有方法的数据类型,可以将自身变量及自身变量地址赋值给对应接口类型变量
  2. select 会随机选择一个可用通道做收发操作。
  3. 给一个nil channel 发送数据,造成永远阻塞。
  4. 常量不同于变量在运行期分配内存,常量通常会被编译器在预处理阶段直接展开,作为指令数据使用,所以常量无法寻址。
  5. nil可以用作interface、function、pointer、map、slice和channel的空值。但是如果不特别指定的话,Go语言不能识别类型。

twenty first 20211216

  1. 接口类型中除了有静态类型,还有动态类型和动态值,当且仅当动态值和动态类型都为nil时,接口类型值才为nil;接口类型的变量存储了两个内容:赋值给变量实际的值和这个值的类型描述。更准确的说,值是底层实现了接口的实际数据项目,而类型描述了这个项目完整的类型。

twenty second 20211217

  1. 有方向的channel不可以被关闭
  2. map需要初始化才能使用,且指针不支持索引。
  3. go语言中,左大括号不能放在单独的一行。
  4. 字面量初始化切片的时候,可以指定索引,没有指定索引的元素会在前一个索引基础之上加一。

twenty third 20211218

  1. 函数中的声明必须要使用,但可以有未使用的全局变量。函数的参数未使用也是可以的。
  2. 当格式化输出时会自动使用String()方法。

twenty forurth 20211219

  1. 导入未使用的包,需要使用下划线 _ 作为这个包的名字。
  2. 不能对nil的map 直接赋值,需要使用make初始化,但可以使用append函数对为nil的 slice增加元素。
  3. 使用make创建map变量时可以指定第二个参数 ,不过会被忽略。cap()函数适用于数组、数组指针、slice和channel,不适用于map,可以使用len()返回map的元素个数。
  4. nil 用于表示interface、函数、maps、slices和channels的“零值”。
  5. Go语言中提供了一种简短的变量声明方式 变量名 := 表达式 用来声明和初始化函数内部的局部变量,变量的类型根据表达式自动推导。不能使用段变量声明设置结构体字段值。

twenty fifth 20211220

  1. 用字面量初始化数组,slice和map时,最好是在每个元素后面加上逗号,即使是声明在一行或者多行都不会出错。
  2. byte是uint8的别名,别名类型无需强制转换,可直接转换。
  3. 常量未使用,是可以编译通过的
  4. 常量组中如不指定类型和初始化值,则与上一行非空常量右值相同。
  5. 不能给string类型变量赋值 nil

twenty sixth 20211221

  1. 表达式通常是求值代码,可作为右值或参数使用;而语句表示完成一个任务,比如if、for语句等。表达式可以作为语句使用,但语句不能当作表达式。
  2. 使用变量简短声明符号:=时,如果符号左边有多个变量,只需要保证至少有一个变量是新声明的,并对已定义的变量进行赋值操作。
  3. := 操作符不能用于结构体字段赋值。
  4. Go里面采用 ^ 作为按位取反运算符,。按位取反之后返回一个每个bit位都取反的数,对于有符号的整数来说,是按照补码进行取反操作的(快速计算方法:对数a取反,结果为-(a+1)),对于无符号整数来说就是按位取反。注意:如果为二元运算符,^表示按位异或。

twenty seventh 20211222

  1. go语言的switch虽然没有break,但如果case完成程序会默认break。

twenty eighth 20211223

  1. 函数只能与nil比较
  2. map[key]struct 中 struct 是不可寻址的,所以无法直接赋值
  3. 在方法中,指针类型的接收者必须是合法指针(包括nil),或能获取实例地址。
  4. 检查map是否含有某一元素,直接判断元素的值并不是一种合适的方式。最可靠的操作是使用访问map时返回的第二个值。

twenty ninth 20211224

  1. 从已关闭的缓冲通道接收数据,返回已缓冲数据或者零值;
  2. 无论接收还是发送,nil通道都会阻塞
  3. 不可寻址的结构体不能调用带结构体指针接收者的方法
  4. 不能使用多级指针调用方法
  5. 通过类型引用的方法表达式会被还原成普通函数样式,接收者是第一个参数,调用时显示传参。类型可以是T或*T,只要目标方法存在于该类型的方法集中就可以。

thirtieth day 20211229

  1. 一个基础切片派生出的子切片的长度可能大于基础切片的长度。假设基础切片是baseSlice, 使用操作符[low, high],有如下规则: 0 <= low <= high <= cap(baseSlice),只要上述满足这个关系,下表low和high都可以大于len(baseSlice)
  2. 当指针值赋值给变量或者作为函数参数传递时,会立即计算并赋值该方法执行所需的接收者对象,与其绑定,以便在稍后执行时,能隐式地传入接收者参数。

thirtieth one day 20220107

  1. 递增运算符++ 和递减运算符–的优先级低于解引用运算符* 和取址运算符&,解引用运算符和取址运算符的优先级低于选择器 . 中的属性选择操作符。