rune 类型的官方解释如下:
// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
type rune = int32
rune 是 int32 的别名,几乎在所有方面等同于 int32,它用来区分字符值和整数值。
仅仅看这段描述并不能看出 rune 类型的特殊之处。
通过一段代码来尝试以下,看看 rune 的特别之处。
func main() {
str := "米虫 is cool"
fmt.Println("STR LEN - ", len(str))
}
上文代码中 str 字符串的长度输出会是多少呢?2个汉字2个空格6个字母。
STR LEN - 14
输出的结果并不是预想中的 10 位。
原因是在 Go 中 string 的底层是通过 []byte 来实现的。
其中中文在 Unicode 编码中是占用2个字节,在 utf-8 编码下占用3个字节,因此2个汉字=6个字节,长度为6+2+6=14。
但是如果我们希望获得准确的字符长度呢?总不能自行去判断字符的类型进行加减乘除吧。
第一种方案是,通过 Go 的 RuneCountInString() 函数取得真实的字符串长度。
func main() {
str := "米虫 is cool"
fmt.Println("STR LEN - ", utf8.RuneCountInString(str))
}
这个函数内部实际就是遍历整个字符串,判断字符所在的区域从而动态的将指针后跳+1+2+3,最后计算出真实的长度。
emm...虽然是 API 函数,但是总觉得不够优雅。
第二种方案就是通过 []rune 来接收字符串,代码如下:
func main() {
str := "米虫 is cool"
fmt.Println("STR LEN - ", len([]rune(str)))
}
可以理解为将 str 转为 []rune 数组,然后计算 []rune 数组的长度即可。
我们前面提到,string 在底层默认通过 []byte,在 Go 中 byte 和 rune 的区别是什么?
// byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
// used, by convention, to distinguish byte values from 8-bit unsigned
// integer values.
type byte = uint8
// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
type rune = int32
rune 和 byte 非常类似,都是可用来表示字符类型的变量类型:
因为 byte 数字范围较小,所以用来表示中文字符的时候,utf-8 需要使用3个 byte。
当前还没有观点发布,欢迎您留下足迹!
在 Go 中函数可以接受值传递和指针传递,使用时就涉及到 & 内存地址(指针)与 * 指针赋值的使用,它们的区别是什么?在实际业务使用中,值传递和指针传递的分别应对什么场景需要?针对使用时机进行分析。
GoLand 在保存代码时,可以自动调用 gofmt 和 goimports 实现自动格式化代码,在新版本中可以通过 File Watchers 插件来完成这些配置,配置位置位于File
Go1.11版本开始支持包依赖管理工具,新增了GOPROXY环境变量,用于配置依赖包下载代理,通过代理配置可以实现翻墙下载一些所需的依赖包,可以说相当实用
对于绝大多数新的 Go 项目而言,因为使用 go modules 管理包依赖从而无需要关注工程的目录位置,但是对于一些旧/历史工程在导入 GoLand 之后会出现全面飘红,这个时候就需要逐一排查问题
调试 Go 程序报错 xx is shadowed during return,方法在返回的时候不是预期的返回结果,错误的产生应当是在相同作用域中出现了同名的变量导致,根据实际业务场景进行修改
Go语言中的接口采用的是隐式实现,不需要去申明实现,只需要直接实现接口所定义的全部方法即可,同时区分了直接实现与指针实现两种形态,在实际使用时需要注意和关注