首页 > 其他分享 >Go语言错误总结(二)

Go语言错误总结(二)

时间:2022-11-25 13:02:33浏览次数:35  
标签:总结 slice string 错误 int fmt nil Go main


8、使用“nil” Slices and Maps

在一个nil的slice中添加元素是没问题的,但对一个map做同样的事将会生成一个运行时的panic。

正确代码:

package main
func main() {
var s []int
s = append(s, 1)
}

错误代码:


package main
func main() {
var m map[string]int
m["one"] = 1
}

运行错误:

panic: assignment to entry in nil map

9、Map的容量

你可以在map创建时指定它的容量,但你无法在map上使用cap()函数。

错误代码:

 

package main
func main() {
m := make(map[string]int, 99)
cap(m)
}

编译错误:

 

./main.go:5:5: invalid argument m (type map[string]int) for cap

10、字符串不会为nil

这对于经常使用nil分配字符串变量的开发者而言是个需要注意的地方。


package main
func main() {
var x string = nil
if x == nil {
x = "default"
}
}

编译错误:


./main.go:4:6: cannot use nil as type string in assignment
./main.go:5:7: invalid operation: x == nil (mismatched types string and nil)

正确代码:


package main
func main() {
var x string
if x == "" {
x = "default"
}
}

11、Array函数的参数

如果你是一个C或则C++开发者,那么数组对你而言就是指针。当你向函数中传递数组时,函数会参照相同的内存区域,这样它们就可以修改原始的数据。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])
}

运行结果:


[7 2 3]
[1 2 3]

如果你需要更新原始数组的数据,你可以使用数组指针类型。

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 [7 2 3]
}

运行结果:

&[7 2 3]
[7 2 3]

另一个选择是使用slice。即使你的函数得到了slice变量的一份拷贝,它依旧会参照原始的数据。

package main
import "fmt"
func main() {
x := []int{1, 2, 3}
func(arr []int) {
arr[0] = 7
fmt.Println(arr) //prints [7 2 3]
}(x)
fmt.Println(x) //prints [7 2 3]
}

运行结果:

[7 2 3]
[7 2 3]

12、在Slice和Array使用“range”语句时的出现的不希望得到的值

如果你在其他的语言中使用“for-in”或者“foreach”语句时会发生这种情况。Go中的“range”语法不太一样。它会得到两个值:第一个值是元素的索引,而另一个值是元素的数据。

package main

import "fmt"
func main() {
x := []string{"a", "b", "c"}
for v := range x {
fmt.Println(v) //prints 0, 1, 2
}
}

运行结果:

0
1
2
package main
import "fmt"
func main() {
x := []string{"a", "b", "c"}
for _, v := range x {
fmt.Println(v) //prints a, b, c
}
}

运行结果:

a
b
c

13、Slices和Arrays是一维的

看起来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>
}

运行结果:


 


[0 1 2 3 4 5 6 7] 0xc4200140a0
[[0 1 2 3] [4 5 6 7]] 0xc4200140a0

关于多维array和slice已经有了专门申请,但现在看起来这是个低优先级的特性。

14、访问不存在的 Map Keys

这对于那些希望得到“nil”标示符的开发者而言是个技巧(和其他语言中做的一样)。如果对应的数据类型的“零值”是“nil”,那返回的值将会是“nil”,但对于其他的数据类型是不一样的。检测对应的“零值”可以用于确定map中的记录是否存在,但这并不总是可信(比如,如果在二值的map中“零值”是false,这时你要怎么做)。检测给定map中的记录是否存在的最可信的方法是,通过map的访问操作,检查第二个返回的值。

package main
import "fmt"
func main() {
x := map[string]string{"one": "a", "two": "", "three": "c"}
if v := x["two"]; v == "" {
fmt.Println("no entry")
}
}运行结果:


 


no entry


 


package main
import "fmt"
func main() {
x := map[string]string{"one": "a", "two": "", "three": "c"}
if _, ok := x["two"]; !ok {
fmt.Println("no entry")
} else {
fmt.Println("exist")
}
}

运行结果:

exist

标签:总结,slice,string,错误,int,fmt,nil,Go,main
From: https://blog.51cto.com/u_13940603/5886363

相关文章

  • Go语言错误总结(五)
    29、未导出的结构体不会被编码以小写字母开头的结构体将不会被(json、xml、gob等)编码,因此当你编码这些未导出的结构体时,你将会得到零值。packagemainimport("encoding/......
  • Go语言错误总结(四)
    22、内建的数据结构操作不是同步的即使Go本身有很多特性来支持并发,并发安全的数据集合并不是其中之一,确保数据集合以原子的方式更新是你的职责。Goroutines和channels是实现......
  • Go 操作 MySQL 数据库
    这一期讲一讲如何使用Go操作MySQL数据库,这里就不讲MySQL的安装以及配置了,但要记得开启MySQL服务,我这里使用的是MySQL8.0.20版本。加载数据库驱动想要连接到数据......
  • Go 的 MySQL 预处理、MySQL 事务
    预处理是什么在普通SQL语句执行过程中,客户端会对SQL语句进行占位符替换,从而得到要执行的完整SQL语句,客户端再将此SQL语句发送到服务端执行,服务端最后把结果返回给客......
  • go实现投票并实时打印投票信息
    packagemainimport"fmt"varstudents[]Studentvarflagbool=truetypeStudentstruct{noint//候选人编号namestring//候选热姓名countint//得票数}fun......
  • 咕噜校园项目总结
    咕噜校园项目功能解刨技术分析校园后台:正方软件后台系统抓包登录:抓取账号密码,看看加密各方面查看请求参数成功和失败动作课表查询抓取URL查看请求参数解......
  • 4 django_Adimn账户
    1.创建管理员账号退出服务器输入命令pythonmanage.pycreatesuperuser启动服务器pythonmanage.pyrunserver输入网址:http://127.0.0.1:8000/admin/logi......
  • 二分查找总结
    二分查找二分查找也常被称为二分法或者折半查找(BinarySearch),每次查找时通过将待查找区间分成两部分并只取一部分继续查找,将查找的复杂度大大减少。对于一个长度为O(n) ......
  • 错误 CS1617 Invalid option '7.3' for /langversion; must be ISO-1, ISO-2, Default
    一年前的程序版本拉下来需要改动下,突然生成程序报这个错。解决方法,网上说修改项目属性-生成-高级,语言版本选择default。我这个项目就不能修改,后来查了下https://stac......
  • GO mod not found
    Goget下载包的时候,会报错:go.modfilenotfoundincurrentdirectoryoranyparentdirectory.解决方法:初始化项目,比如我的项目名称叫GOWORKSPACEPSD:\goWorkSp......