函数function
go函数不支持嵌套、重载和默认参数
但支持以下特性:
无需声明原型、不定长度变参、多返回值、命名返回值参数、匿名函数、闭包
定义函数使用关键字func,且左大括号不能另起一行
函数也可以作为一种类型使用
defer
执行方式类似其他语言的析构函数,在函数体执行结束后按照调用顺序的相反顺序逐个执行
即使函数发生严重错误也会执行
支持匿名函数的调用
常用于资源清理、文件关闭、解锁以及记录时间等操作
通过与匿名函数配合可在return之后修改函数计算结果
如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer时即已经获得了拷贝,否则这是引用某个变量的地址
go没有异常机制,但有panic和recover模式来处理错误
panic可以在任何地方引发,但recover只有在defer调用的函数中有效
结构struct
go中的struct与c中struct非常相似,并且go没有class
使用type <Name> struct{}定义结构,名称遵循可见性
支持指向自身的指针类型成员
支持匿名结构,可用作成员或定义成员变量
匿名结构也可以用于map的值
可以使用字面值对结构进行初始化
允许直接通过指针来读写结构成员
相同类型的成员可进行直接拷贝赋值
支持==与!=比较运算符,但不支持>或<
支持匿名字段,本质上时定义了以某个类型名为名称的字段
嵌入结构作为匿名字段看起来像继承,但不是继承
可以使用匿名字段指针
方法method
go中虽没有class,但依旧有method
通过显示说明receiver来实现与某个类型的组合
只能为同一个包中的类型定义方法
receiver可以是类型的值或者指针
不存在方法重载
可以使用值或指针来调用方法,编译器会自动完成转换
从某种意义上来说,方法是函数的语法糖
因为receiver其实就是方法所接受的第一个参数(Method Value vs. Method Expression)
如果外部结构和嵌入结构存在同名方法,则优先调用外部结构的方法
类型别名不会拥有底层类型所附带的方法
方法可以调用结构中的非公开字段
接口interface
接口是一个或多个方法签名的集合
只要某个类型拥有该接口所有方法签名,即算实现该接口
无需显示声明实现了哪个接口,这称为Structural Typing
接口只有方法声明,没有实现,没有数据字段
接口可以匿名嵌入其他接口,或嵌入结构中
将对象赋值给接口时,会发生拷贝
而接口内部存储的时指向这个复制品的指针,即无法修改复制品的状态,也无法获取指针
只有当接口存储的类型和对象都为nil时,接口才等于nil
接口调用不会做receiver的自动转换
接口同样支持匿名字段方法
接口也可以实现类似OOP中的多态
空接口可以作为任何类型数据的容器
反射reflection
反射可大大提高程序的灵活性,使得interface{}有更大的发挥余地
反射使用TypeOf和ValueOf函数从接口中获取目标对象信息
反射会将匿名字段作为独立字段(匿名字段本质)
想要利用反射修改对象状态,前提是interface.data是settable,即pointer-interface
通过反射可以“动态”调用方法