2.1
除了main包外,所有的package都会生成*.a文件。
2.2
字节
每个byte是一个字节,数组byte[]是若干个字节,int、int32和float都是4个字节。
iota
用于枚举,每次加1。
##大写
包(可导出),class(public函数)。
数组
- 长度也是数组类型的一部分,[3]int和[4]int是不同的类型,数组不能改变长度。
- 赋值:数组的赋值是值赋值,当把数组传入函数时,传入的是数组副本,当传入slice时,使用的是指针。
动态数组(slice)
数组的声明为 var arr [10]int
slice的声明为 var sli []int
- 指定长度:a := arr[2:5] 意为arr[2] arr[3] arr[4]
- 对slice的slice可以在cap上拓展
- len:长度
- cap:最大容量
函数
###变参数
传入一个slice:例如func myfunc(arg …int) {}
###传指针
传指针需要参数为int, 传入的参数为¶m,操作的是param,但是string、slice和map的底层实现机制类似指针,可以不取地址而直接传递。
defer
多个defer:后进先出
panic 和 recover
如果没有任何panic,recover会返回nil。
包导入
由于A包会导入其他BC包,BC包又会导入其他DE包,因此首先对DE、BC、A按顺序执行(导入、初始化变量、执行可能有的init函数的工作)。最后执行main函数。
像fmt这种系统自带的包是在GOROOT路径下的。
struct
###匿名字段,实现字段的继承
只声明类型,不声明名称。如果在struct A内声明了匿名的struct B,会嵌入式导入该struct的全部字段,作为A的成员。
###匿名字段重复时,的访问的方式
比如struct A里有字段x 和 struct B,其中struct B里也有字段x,则直接访问A.x可以访问A中的字段,A.B.x可以访问B中的字段。
2.5
class面向对象
struct的函数,可以访问其成员变量。
有传值和传指针两种方式
// 传值:改变成员的副本
func (r Rectangle) area() float64{
return r.w * r.h
}
// 传指针:改变成员
func (r* Rectangle) area() float64{
return r.w * r.h
}
自定义类型均可自定义方法
// struct
type Circle struct{
r float64
}
func (c Circle) area() float64{
return c.r * c.r * math.Pi
}
// 其他类型别名
type CircleList []Circle
func (cl CircleList) SetFirstCircle(idx int) (isOk bool){
cl[idx] = "Black"
return true
}
指针的访问
ptr.val 和 *ptr.val都是取的指针对应地址的值。
#method继承
struct A 的字段中包含 struct B,则相当于B是A的基类,A具备B的所有属性,则派生类A可以重写基类A的函数,实现method的继承。
typedef Human struct{
name string
age int
}
typedef Student struct{
Human
school string
}
func (h *Human) SayHi(){
fmt.Print("hi, i am %s", h.name)
}
func (s *Student) SayHi(){
fmt.Print("hi, i am %s, from %s", s.name, s.school)
}
2.6 interface
interface就是一组方法的集合,谁实现了该集合的所有方法,就实现了该interface。
interface的变量存实现了该interface的对象。例如interface 变量m,可以存Human,Student,或者Employee值。
因此,可以定义一个interface的slice,其中可以存放任意类型的变量。
// 定义接口类型
type Men interface{
SayHi()
Sing(lyrics string)
}
// 实例化接口变量
var i Men
// 接口i可存储Student类型的对象
i = mike
i.SayHi()
i.Sing("hello")
// 接口i可存储Employee类型的对象
i = Tom
i.SayHi()
i.Sing("hello")
// 实例化接口slice变量
isli := make([]Men, 3)
// 每个接口变量可以存储不同类型的对象
isli[0],isli[1],isli[2] = paul,sam,mike
// 分别对每个类型调用接口,但调用方式都一样
for _, i := range isli{
i.SayHi()
}
##空interface
var a interface
var i int = 5
var s string = "hello"
// 接口可存任意类型的数值
a = i
a = s
函数参数为interface,则可接收任意类型变量为参数
函数返回为。。。。,则可返回。。。。。。。。。。
通过interface,可让函数接收各种参数。
comma-ok测试
if value, ok := element.(int); ok{
fmt.Printf("list[%d] is an int and its value is %d\n",
}
for index, element := range list{
switch value := element.(type){
case int:
fmt.Pritf("list[%d] is an int and its value is %d\n, index, value)
case string:
fmt.Printf("list[%d] is an string and its value is %s\n, index, value)
}
}
嵌入式interface
type ReaderWriter interface{
Reader
Writer
}
#channel
channel可以关闭,Close(chan)