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

Go语言错误总结(四)

时间:2022-11-25 12:32:32浏览次数:32  
标签:总结 错误 0x2 fmt func Printf Go 08b main


22、内建的数据结构操作不是同步的

即使Go本身有很多特性来支持并发,并发安全的数据集合并不是其中之一,确保数据集合以原子的方式更新是你的职责。Goroutines和channels是实现这些原子操作的推荐方式,但你也可以使用“sync”包,如果它对你的应用有意义的话。

23、String在“range”语句中的迭代值

索引值(“range”操作返回的第一个值)是返回的第二个值的当前“字符”(unicode编码的point/rune)的第一个byte的索引。它不是当前“字符”的索引,这与其他语言不同。注意真实的字符可能会由多个rune表示。如果你需要处理字符,确保你使用了“norm”包(golang.org/x/text/unicode/norm)。

string变量的for range语句将会尝试把数据翻译为UTF8文本。对于它无法理解的任何byte序列,它将返回0xfffd runes(即unicode替换字符),而不是真实的数据。如果你任意(非UTF8文本)的数据保存在string变量中,确保把它们转换为byte slice,以得到所有保存的数据。

package main
import "fmt"
func main() {
data := "A\xfe\x02\xff\x04"
for _, v := range data {
fmt.Printf("%#x ", v)
}
//prints: 0x41 0xfffd 0x2 0xfffd 0x4 (not ok)
fmt.Println()
for _, v := range []byte(data) {
fmt.Printf("%#x ", v)
}
//prints: 0x41 0xfe 0x2 0xff 0x4 (good)
}

运行结果:

0x41 0xfffd 0x2 0xfffd 0x4 
0x41 0xfe 0x2 0xff 0x4

24、对Map使用“for range”语句迭代

如果你希望以某个顺序(比如,按key值排序)的方式得到元素,就需要这个技巧。每次的map迭代将会生成不同的结果。Go的runtime有心尝试随机化迭代顺序,但并不总会成功,这样你可能得到一些相同的map迭代结果。所以如果连续看到5个相同的迭代结果,不要惊讶。

package main
import "fmt"
func main() {
m := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}
for k, v := range m {
fmt.Println(k, v)
}
}

而且如果你使用Go的游乐场(https://play.golang.org/),你将总会得到同样的结果,因为除非你修改代码,否则它不会重新编译代码。

25、"switch"声明中的失效行为

在“switch”声明语句中的“case”语句块在默认情况下会break。这和其他语言中的进入下一个“next”代码块的默认行为不同。

package main
import "fmt"
func main() {
isSpace := func(ch byte) bool {
switch ch {
case ' ':
case '\t':
return true
}
return false
}
fmt.Println(isSpace('\t'))
fmt.Println(isSpace(' '))
}

运行结果:

true
false

你可以通过在每个“case”块的结尾使用“fallthrough”,来强制“case”代码块进入。你也可以重写switch语句,来使用“case”块中的表达式列表。

package main
import "fmt"
func main() {
isSpace := func(ch byte) bool {
switch ch {
case ' ':
fallthrough
case '\t':
return true
}
return false
}
fmt.Println(isSpace('\t'))
fmt.Println(isSpace(' '))
}
package main
import "fmt"
func main() {
isSpace := func(ch byte) bool {
switch ch {
case ' ', '\t':
return true
}
return false
}
fmt.Println(isSpace('\t'))
fmt.Println(isSpace(' '))
}

运行结果:

true
true

26、自增和自减

许多语言都有自增和自减操作。不像其他语言,Go不支持前置版本的操作。你也无法在表达式中使用这两个操作符。

错误代码:

package main
import (
"fmt"
)
func main() {
data := []int{1, 2, 3}
i := 0
++i
fmt.Println(data[i++])
}

编译错误:


 


./main.go:10:2: syntax error: unexpected ++, expecting }

正确代码:

package main
import "fmt"
func main() {
data := []int{1, 2, 3}
i := 0
i++
fmt.Println(data[i])
}

27、按位NOT操作

许多语言使用 ~作为一元的NOT操作符(即按位补足),但Go为了这个重用了XOR操作符(^)。

错误代码:

package main
import "fmt"
func main() {
fmt.Println(~2)
}

编译错误:


 


./main.go:6:14: bitwise complement operator is ^

正确代码:

package main
import "fmt"
func main() {
var d uint8 = 2
fmt.Printf("%08b\n", ^d)
}

Go依旧使用^作为XOR的操作符,这可能会让一些人迷惑。

如果你愿意,你可以使用一个二元的XOR操作(如, 0x02 XOR 0xff)来表示一个一元的NOT操作(如,NOT 0x02)。这可以解释为什么^被重用来表示一元的NOT操作。

Go也有特殊的‘AND NOT’按位操作(&^),这也让NOT操作更加的让人迷惑。这看起来需要特殊的特性/hack来支持 A AND (NOT B),而无需括号。

package main
import "fmt"
func main() {
var a uint8 = 0x82
var b uint8 = 0x02
fmt.Printf("%08b [A]\n", a)
fmt.Printf("%08b [B]\n", b)
fmt.Printf("%08b (NOT B)\n", ^b)
fmt.Printf("%08b ^ %08b = %08b [B XOR 0xff]\n", b, 0xff, b^0xff)
fmt.Printf("%08b ^ %08b = %08b [A XOR B]\n", a, b, a^b)
fmt.Printf("%08b & %08b = %08b [A AND B]\n", a, b, a&b)
fmt.Printf("%08b &^%08b = %08b [A 'AND NOT' B]\n", a, b, a&^b)
fmt.Printf("%08b&(^%08b)= %08b [A AND (NOT B)]\n", a, b, a&(^b))
}

28、操作优先级的差异

除了”bit clear“操作(&^),Go也一个与许多其他语言共享的标准操作符的集合。尽管操作优先级并不总是一样。

package main
import "fmt"
func main() {
fmt.Printf("0x2 & 0x2 + 0x4 -> %#x\n", 0x2&0x2+0x4)
//prints: 0x2 & 0x2 + 0x4 -> 0x6
//Go: (0x2 & 0x2) + 0x4
//C++: 0x2 & (0x2 + 0x4) -> 0x2
fmt.Printf("0x2 + 0x2 << 0x1 -> %#x\n", 0x2+0x2<<0x1)
//prints: 0x2 + 0x2 << 0x1 -> 0x6
//Go: 0x2 + (0x2 << 0x1)
//C++: (0x2 + 0x2) << 0x1 -> 0x8
fmt.Printf("0xf | 0x2 ^ 0x2 -> %#x\n", 0xf|0x2^0x2)
//prints: 0xf | 0x2 ^ 0x2 -> 0xd
//Go: (0xf | 0x2) ^ 0x2
//C++: 0xf | (0x2 ^ 0x2) -> 0xf
}

运行结果:

0x2 & 0x2 + 0x4 -> 0x6
0x2 + 0x2 << 0x1 -> 0x6
0xf | 0x2 ^ 0x2 -> 0xd

标签:总结,错误,0x2,fmt,func,Printf,Go,08b,main
From: https://blog.51cto.com/u_13940603/5886351

相关文章

  • 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......
  • Go语言开发环境搭建
    1go下载安装地址:https://golang.google.cn/dl/安装路径自己选一个,比如D:/go,qita安装都选下一步即可安装完把D:/go/bin添加到系统环境变量,就可以了,在CMD中输入......
  • GEE|Google Earth Engine报错Error in map(ID=LC08_123038_20190121) Element.copyPro
    本文以LANDSAT/LC08/C01/T1_SR数据集为例介绍Thesourceparameterisrequire应该如何解决。问题描述GEE平台提供了影像在线处理,在完成对数据集处理后,想要对数据进行......