有关于Go语言的一些tips
Getters and Setters
Go也可以创建Getters
and Setters
,而且它们并不需要以get或set开头。
分号
Go大部分的;
可以省略,是因为它的语法分析器会自动为你加上。
短声明
1 | f, err := os.Open(name) |
在第二个语句中,d
是新建变量,而err
是重新赋值。
多重赋值
Go中没有逗号,
运算符,++
和--
是声明而非语句,但你可以用并列多重赋值来在for
循环中操作多个变量1
2
3for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
switch中合并多个case
使用逗号,
隔开即可1
2
3
4
5
6
7func shouldEscape(c byte) bool {
switch c {
case ' ', '?', '&', '=', '#', '+', '%':
return true
}
return false
}
带标签的break
可以break
指定的loop
,即先为循环设置label,再break label。注意第二个case
中的(break Loop
),多重嵌套中会很顺手。同时注意这里使用到了不跟表达式的switch
.
同样的,continue
也可跟标签,但只限于循环中。
1 | Loop: |
Type switch
用于动态地发现接口变量类型,使用类型断言
并在括号中传入 type
。1
2
3
4
5
6
7
8
9
10
11
12
13
14var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t has
case bool:
fmt.Printf("boolean %t\n", t) // t has type bool
case int:
fmt.Printf("integer %d\n", t) // t has type int
case *bool:
fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}
new和make
Go有两个基本分配操作,new和make,new为变量分配内存并置零(不同于其它语言的初始化)。
make则为slice , map和chan专用的,它不返回零值变量,而是初始化。
slice
slice
其实是对array
进行了再包装(pointer, length, and capacity),它类似指针传递,但需要注意类似append
这样的操作返回的是新的slice。
不同于C的是,array也是值传递的,也就是说会产生一个新的数组Copy。
init函数
每个源文件都可以有init方法,它在所有变量初始化之后执行。它可以用来实现无法在声明中完成的初始化,确认和修复初始执行环境。1
2
3
4
5
6
7
8
9
10
11
12
13func init() {
if user == "" {
log.Fatal("$USER not set")
}
if home == "" {
home = "/home/" + user
}
if gopath == "" {
gopath = home + "/go"
}
// gopath may be overridden by --gopath flag on command line.
flag.StringVar(&gopath, "gopath", gopath, "override default GOPATH")
}
方法:Pointers vs. Values
receiver
为值的方法可被值和指针调用,而指针receiver
的方法只能被指针调用。
for range中的变量
for i:=range varaible
中,变量i
会在每一轮循环中重复使用,如果直接在匿名函数中使用i,将易产生问题,这里有个种方式可行。一、使用带参数的匿名函数将i作为参数传递;二、在循环体开始处使用新变量保存i值,如i:=i
,这是合法的。
并发与并行
Go是并发语言而非并行语言,所谓并发:程序由多个独立执行组件组成;而并行:在多个CPU上平行运算以提高效率
panic && recover
panic
函数会立即停止当前函数执行,并回溯gorouting的调用栈,执行之前defer方法,如果回溯到顶层,那么程序就退出了。
内建的recover()
函数可以中止这个回溯过程并将最初传递给panic的参数以error
的形式返回。
注意,recover只能在defer
中使用,否则返回nil.