指针
GO 语言像 C 一样有指针,可以通过指针访问数据,但是 GO 的指针要安全的多:
- 首先,访问空指针会直接报错
- 指针不能被当做数据来访问(这样就避免了越界访问)
- 指针本身也不能进行加减运算,即指针不能移动,只能被赋予变量的地址
- 只要指针没有消失,它所指向的变量就一直存在,即便该变量所在作用域已经结束
有了以上这些保护,指针在给程序带来灵活性的同时,就可以尽可能的避免随之而来的风险。
结构体
和其他语言一样,结构体就是多个变量的集合,例如
type Vertex struct {
X,Y int
Z float64
}
在访问结构体内部值时,使用.
,这和 C/C++ 是一致,但要注意,如果通过结构体指针访问内部变量,同样使用.
,而不是像其他类 C 语言一样使用->
,我想这主要是和 GO 语言对指针做了大量保护,使得通过指针和通过变量本身操作,没有本质的区别。
数组
数组的定义语法为
var <array_name> [<array_size>]<array_type>
或者对于有初值的数组,可以如此定义(这时,数据长度由初始值隐含)
<array_name> := []<array_type>{<initial_values>}
GO 语言提供内置的函数len
获得数组的长度,所有越界的访问都无法通过编译,避免了数据越界的风险。
GO 语言中,可以对数组进行切片,这一点很像 python。切片实际上是对数据的一种引用,而且可以继承数据的整个长度作为切片的容量。
数组和切片可以通过append
函数增加长度,每一次增加长度时,如果超出了容量,都会导致内存的重新分配,其实这样的效率并不高,对于长度灵活变化的数据还是应该使用列表更合适。
对于长度在运行中才能确定的数据,需要通过内置函数make
生成,下面是基于 go tour 的一个例子
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
fig := make([][]uint8,dy)
for i := range fig {
fig[i] = make([]uint8,dx)
for j:= range fig[i] {
fig[i][j] = uint8(i^j)
}
}
return fig
}
func main() {
pic.Show(Pic)
}
遍历
对于数据和切片,可以通过关键字range
进行遍历,这一点也很像 python:
package main
import (
"fmt";
"math"
)
var pow [10]int
func main() {
for i := range pow {
pow[i] = int(math.Pow(2.0,float64(i)))
}
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
}
字典
GO 语言中字典类型使用map
关键字代表,不分有序和无序,即没有 C++ 中 map 和 hash 的区别。
定义一个字典可以使用var <map_name> map[<key_type>]<value_type>
,但这样生成的字典是空,如法操作,必须通过make
函数或者直接赋初始值的方式生成。例如
type Vertex struct {
Lat, Long float64
}
...
m := make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68433, -74.39967,
}
或者
var m = map[string]Vertex{
"Bell Labs": Vertex{
40.68433, -74.39967,
},
"Google": Vertex{
37.42202, -122.08408,
},
}
或者更进一步简化
m := map[string]Vertex{
"Bell Labs": {40.68433, -74.39967},
"Google": {37.42202, -122.08408},
}
字典的访问方式同其他语言类似,而且同样可以使用range
进行遍历,即key,value := range some_map
。
可以使用delete(som_map, key_to_delete)
函数删除字典中特定的 key-value 对,在访问字典内容时,可以使用elem, ok := some_map[some_key]
来获取数据是否存在的标志。
函数类型变量
和很多现代语言一样,GO 语言同样支持函数类型的变量,下面就是利用这个功能做的fibonacci
函数
package main
import "fmt"
// fibonacci is a function that returns a function that returns an int.
func fibonacci() func() int {
value, last := 0, 1
return func() int {
v := value
value += last
last = v
return v
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
网友评论