1,slice append
[0 0 0 0 0 1 2 3]
[1 2 3 4]
append一定是在长度后追加
type MyInt1 int 新类型
type MyInt2 = int int别名
slice [i:j:k] 长度=j-i 容量=k-i 起始索引 i 到 索引j-1
只有slice和chanel可以用cap函数
go打印 %+d 表示打印十进制的符号 比如fmt.Printf("%+d %+d",-5,+5) 输出为-5 +5
闭包引用的外部变量的地址,外部变量地址变了,闭包内引用的变量肯定改变了
type Person struct {
age int
}
funcmain() {
person := &Person{28}
// 1.
defer fmt.Println(person.age) // 参数就是 28
// 2.
defer func(p *Person) { // 参数为 Person指针 指向的是 &Person{28}
fmt.Println(p.age)
}(person)
// 3.
defer func() {
fmt.Println(person.age) //闭包 输出 29 person本身改变了
}()
person = &Person{29}
}
函数参数为 interface{} 时可以接收任何类型的参数,包括用户自定义类型等,即使是接收指针类型也用 interface{},而不是使用 *interface{}。
永远不要使用一个指针指向一个接口类型,因为它已经是一个指针。
在go中,在if中else if else
if a:= 1; false{
}else{
fmt.Println(a) //输出1
}
3,一个函数秒懂defer
funcmain(){
a :=1
b :=2
defercalc("1", a, calc("10", a, b))
a =0
defercalc("2", a, calc("20", a, b))
b =1
}
funccalc(indexstring, a, bint)int{
ret := a + b
fmt.Println(index, a, b, ret)
returnret
}
答案及解析:
10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4
给一个结构体Stu绑定方法如 func (stu *Stu) Speak()string{} 或 func (stu Stu)Speak()string{},指针*Stu这两个方法都可以调用,但结构体Stu只能调用Stu的方法。
iota 是 golang 语言的常量计数器,只能在常量的表达式中使用。iota 在 const 关键字出现时将被重置为0,const中每新增一行常量声明将使 iota 计数一次。
4,结构体比较
结构体只能比较是否相等,不能比较大小,相同类型的结构体才能够进行比较,结构体是否相同不但与属性类型有关,还与属性顺序相关。
什么是可比较的呢,常见的有 bool、数值型、字符、指针、数组等,像切片、map、函数等是不能比较的。
5,新类型 type Myint int ,Myint是一个新类型,不能互相赋值;别名 type Myint = int,Myint和int一样,可以互相赋值;
6,nil 只能赋值给指针、chan、func、interface、map 或 slice 类型的变量。
7,init函数
init() 函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等;
一个包可以出线多个 init() 函数,一个源文件也可以包含多个 init() 函数;
同一个包中多个 init() 函数的执行顺序没有明确定义,但是不同包的init函数是根据包导入的依赖关系决定的(看下图);
init() 函数在代码中不能被显示调用、不能被引用(赋值给函数变量),否则出现编译错误;
一个包被引用多次,如 A import B,C import B,A import C,B 被引用多次,但 B 包只会初始化一次;
引入包,不可出现死循坏。即 A import B,B import A,这种情况编译失败;
8,类型断言
类型选择,类型选择的语法形如:i.(type),其中 i 是接口,type 是固定关键字,需要注意的是,只有接口类型才可以使用类型选择。
9,一个 map 中不存在的值时,返回元素类型的零值
10,闭包引用 函数内部引用外部变量,
11,永远不要使用一个指针指向一个接口类型,因为它已经是一个指针
12,结构体只能调用结构体的方法,指针既可以调用结构体的方法也可以调用指针的方法
13,iota 是 golang 语言的常量计数器,只能在常量的表达式中使用。iota 在 const 关键字出现时将被重置为0,const中每新增一行常量声明将使 iota 计数一次。
14,当且仅当动态值和动态类型都为 nil 时,接口类型值才为 nil。即值为nil类型也为nil。
15,for i,v := range 数组,for i,v := range 切片 不一样 range虽然是值拷贝,但切片是个指针,拷贝的是一个指针,里面的数据指针还是指向同一片内存, 数组就不一样了,数组进行值拷贝,在range的时候就是另一个栈空间了。
16,for range 使用短变量声明(:=)的形式迭代变量时,变量 i、value 在每次循环体中都会被重用,而不是重新声明。
17,多重赋值,多重赋值分为两个步骤,有先后顺序:计算等号左边的索引表达式和取址表达式,接着计算等号右边的表达式;赋值;简单的说就是先确定左边的值(表达式要计算出具体的值),在确定右边的值,然后进行赋值
18,强制类型转换 type Myint int var a int = 1 var b Myint = Myint(a)
不可用var b Myint = a.(Myint) 只有接口才使用类型断言
19,自增自减操作。i++ 和 i-- 在 Go 语言中是语句,不是表达式,因此不能赋值给另外的变量。此外没有 ++i 和 --i。
有疑问加站长微信联系(非本文作者)