添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Getters and Setters

Go也可以创建 Getters and Setters ,而且它们并不需要以get或set开头。

分号

Go大部分的 ; 可以省略,是因为它的语法分析器会自动为你加上。

短声明

1
2
f, err := os.Open(name)
d, err := f.Stat()

在第二个语句中, d 是新建变量,而 err 是重新赋值。

多重赋值

Go中没有逗号 运算符, ++ -- 是声明而非语句,但你可以用并列多重赋值来在 for 循环中操作多个变量

1
2
3
for 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
7
func shouldEscape(c byte) bool {
switch c {
case ' ', '?', '&', '=', '#', '+', '%':
return true
}
return false
}

带标签的break

可以 break 指定的 loop ,即先为循环设置label,再break label。注意第二个 case 中的( break Loop ),多重嵌套中会很顺手。同时注意这里使用到了不跟表达式的 switch .

同样的, continue 也可跟标签,但只限于循环中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Loop:
for n := 0; n < len(src); n += size {
switch {
case src[n] < sizeOne:
if validateOnly {
break
}
size = 1
update(src[n])

case src[n] < sizeTwo:
if n+1 >= len(src) {
err = errShortInput
break Loop
}
if validateOnly {
break
}
size = 2
update(src[n] + src[n+1]<<shift)
}
}

Type switch

用于动态地发现接口变量类型,使用 类型断言 并在括号中传入 type

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var 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
13
func 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.