golang 50处陷阱
1.main()函数后面的大括号不能放在单独的一行
2.如果存在未使用的变量,将导致编译失败, 可以使用"_ = value"进行注释
3.如果存在未使用的import,会导致编译失败
4.简式的变量声明仅可以在函数内部使用
5.一个代码块内不用简式重复声明变量, 使用":="声明变量时,左边至少有一个变量未声明过
6.偶然的变量隐藏Accidental Variable Shadowing
- 简式的声明变量,只在当前的代码块内有效
- 可以借助工具帮忙检查: go tool vet -shadow xxx.go
package main
import "fmt"
func main() {
x := 1
fmt.Println(x) //prints 1
{
fmt.Println(x) //prints 1
x := 2
fmt.Println(x) //prints 2
}
fmt.Println(x) //prints 1 (bad if you need 2)
}
不使用显式类型,无法使用“nil”来初始化变量
- nil标志符用于表示interface、函数、maps、slices和channels的“零值”。
- 如果你不指定变量的类型,编译器将无法编译你的代码,因为它猜不出具体的类型。
package main
func main() {
var x = nil //error
var x interface{} = nil //ok
_ = x
}
使用“nil” Slices and Maps
- 在一个nil的slice中添加元素是没问题的,但对一个map做同样的事将会生成一个运行时的panic。
package main
func main() {
var s []int
s = append(s,1) //ok
var m map[]int
m["one"] = 1 //error
}
map的容量:可以在map创建时指定它的容量,但你无法在map上使用cap()函数
字符串不会为nil
- 这对于经常使用nil分配字符串变量的开发者而言是个需要注意的地方。
package main
func main() {
var x string = nil //error
if x == nil { //error
x = "default"
}
var x string //defaults to "" (zero value)
if x == "" {
x = "default"
}
}
数组作为函数的参数
- c/c++中数组作为函数参数是传引用。golang是传的值。
- 在go中,函数内修改数组的数据,函数外是不可见的。
package main
import "fmt"
func main() {
x := [3]int{1,2,3}
func(arr [3]int) {
arr[0] = 7
fmt.Println(arr) //prints [7 2 3]
}(x)
fmt.Println(x) //prints [1 2 3] (not ok if you need [7 2 3])
//可以通过传指针的方式实现:func(arr *[3]int) {...}(&x)
//另外如果只是修改数据,可以使用slice
}
数组和切片使用range语句遍历会得到两个值
数组和切片是一维的
Go好像支持多维的Array和Slice,但不是这样的。尽管可以创建数组的数组或者切片的切片
对于依赖于动态多维数组的数值计算应用而言,Go在性能和复杂度上还相距甚远。
你可以使用纯一维数组、“独立”切片的切片,“共享数据”切片的切片来构建动态的多维数组。
如果你使用纯一维的数组,你需要处理索引、边界检查、当数组需要变大时的内存重新分配。
-
使用“独立”slice来创建一个动态的多维数组需要两步。
- 首先,你需要创建一个外部的slice。
- 然后,你需要分配每个内部的slice。
- 内部的slice相互之间独立。你可以增加减少它们,而不会影响其他内部的slice。
package main
func main() {
x := 2
y := 4
table := make([][]int,x)
for i:= range table {
table[i] = make([]int,y)
}
}
-
使用“共享数据”slice的slice来创建一个动态的多维数组需要三步。
- 首先,你需要创建一个用于存放原始数据的数据“容器”。
- 然后,你再创建外部的slice。
- 最后,通过重新切片原始数据slice来初始化各个内部的slice。
package main
import "fmt"
func main() {
h, w := 2, 4
raw := make([]int,h*w)
for i := range raw {
raw[i] = i
}
fmt.Println(raw,&raw[4])
//prints: [0 1 2 3 4 5 6 7] <ptr_addr_x>
table := make([][]int,h)
for i:= range table {
table[i] = raw[i*w:i*w + w]
}
fmt.Println(table,&table[1][0])
//prints: [[0 1 2 3] [4 5 6 7]] <ptr_addr_x>
}
访问不存在的Map Keys
有疑问加站长微信联系(非本文作者)