if/else 变体
if statement; condition {
}
if condition{
}
switch
switch 下的每个case不必带break,匹配到了某个case之后会自动跳出.
可以使用fallthrough
强制执行后面的case的代码.
如果switch没有条件表达式,它会默认匹配true
也可以判断变量的type:
switch x.(type){
case type:
statement(s);
case type:
statement(s);
/* 你可以定义任意个数的case */
default: /* 可选 */
statement(s);
}
package main
import "fmt"
func main() {
var x interface{}
switch i := x.(type) {
case nil:
fmt.Printf(" x 的类型 :%T",i)
case int:
fmt.Printf("x 是 int 型")
case float64:
fmt.Printf("x 是 float64 型")
case func(int) float64:
fmt.Printf("x 是 func(int) 型")
case bool, string:
fmt.Printf("x 是 bool 或 string 型" )
default:
fmt.Printf("未知型")
}
}
for
可以使用 for.. range
进行迭代:
for key, value := range oldMap {
newMap[key] = value
}
for中的三个条件都可以忽略.
iota
自增+1,多用于枚举
数组
golang中的数组是值类型,修改副本中的元素不会影响原来的数据.
package main
import "fmt"
func main() {
a := [...]string{"USA", "China", "India", "Germany", "France"}
b := a // a copy of a is assigned to b
b[0] = "Singapore"
fmt.Println("a is ", a)
fmt.Println("b is ", b)
}
输出结果:
a is [USA China India Germany France]
b is [Singapore China India Germany France]
数组的大小是类型的一部分。因此[3]int和[2]int是不同的类型。
切片
Golang中切片是数组的抽象,Go中数组长度不可变,但是切片可以.切片本身没有任何数据,它只是对现有数组的引用.
因此,。对切片所做的任何修改都将反映在底层数组中.
可以使用make方法创建切片:
var slice1 []type = make([]type, len)
//也可以简写为
slice1 := make([]type, len)
len()
是切片中元素的数量
cap()
是底层数组中元素的数量
append()
可以用来给切片追加元素,也会改变底层数组的内容,但是在切片cap不大于len的情况下,会扩容导致分配新的数组空间,这种情况下引用该数组的其他切片不被影响.
copy()
不会在两个切片之间建立联系.
map
同样可以使用make
创建,也可以直接初始化:
/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type
/* 使用 make 函数 */
map_variable = make(map[key_data_type]value_data_type)
rating := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 }
如果不初始化,则是一个nil map.
delete(map, key)
用来删除元素
map[key]
获取不存在的key值时,会返回默认值,string返回空字符串,可以使用:
value, ok := map[key]
ok是布尔类型.
函数
可变参数:
func myfunc(arg ...int) {}
函数也是Go中的一种数据类型,可以作为另一个函数的参数.
defer
:当一个函数执行到最后,会逆序执行defer语句,然后return.
指针
声明指针:
var var_name *var-type
var ip *int /* 指向整型*/
var fp *float32 /* 指向浮点型 */
获取指针的值:*ptr
使用指针传递参数:
func change(val *int) {
*val = 55
}
结构嵌套
结构体嵌套
type Address struct { city, state string } type Person struct { name string age int address Address }
匿名字段/提升字段
type Human struct { name string age int weight int } type Student struct { Human // 匿名字段,那么默认Student就包含了Human的所有字段 speciality string }
可以像这样初始化:
mark := Student{Human{"Mark", 25, 120}, "Computer Science"}
字段可以直接访问.
mark.name
如果想导出结构体和它的字段,则首字母必须大写.
结构体是值类型,如果两个结构体中的字段都相等(前提是字段类型可以比较),则认为两个结构体是相等的.
make与new
make
用于内建类型(map, slice,channel)的内存分配.
new
用于各种类型的内存分配,返回的是指针.
函数与方法
方法指的是带接收者(即对象)的函数.
func (t Type) methodName(parameter list)(return list) {
}
func funcName(parameter list)(return list){
}
方法是可以继承的,如果匿名字段实现了一个方法,包含这个匿名字段的struct也能调用这个方法:
type Human struct {
name string
age int
phone string
}
type Student struct {
Human //匿名字段
school string
}
type Employee struct {
Human //匿名字段
company string
}
func (h *Human) SayHi() {
fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
func main() {
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
mark.SayHi()
sam.SayHi()
}
方法还可以重写,即在包含匿名字段的struct再实现一个方法.