golang 50处陷阱

voidFan · · 539 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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来创建一个动态的多维数组需要两步。

    1. 首先,你需要创建一个外部的slice。
    2. 然后,你需要分配每个内部的slice。
    3. 内部的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来创建一个动态的多维数组需要三步。

    1. 首先,你需要创建一个用于存放原始数据的数据“容器”。
    2. 然后,你再创建外部的slice。
    3. 最后,通过重新切片原始数据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


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:voidFan

查看原文:golang 50处陷阱

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

539 次点击  
加入收藏 微博
下一篇:gRPC 基本概念
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传