unicode和 utf8简介
Unicode是一种国际标准,旨在为全球范围内的文本提供一个统一、标准的表示方式。它为每个字符分配一个唯一的数字码点,无论在哪个平台或使用哪种语言,相同的码点总能代表相同的字符。例如,英文的"A"的Unicode码是65,汉字"中"的Unicode码是20013。Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储
UTF-8是Unicode的一种变长字符编码方式,由Ken Thompson和Rob Pike于1992年创建。它使用1到4个字节来表示一个字符,这种设计使得UTF-8能够灵活地表示所有的Unicode码点,同时兼容ASCII码。对于ASCII码中的字符,UTF-8的表示与原编码相同;
UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8 是 Unicode 的实现方式之一。
UTF-8 的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
编辑
严的 Unicode 是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800 - 0000 FFFF),因此严的 UTF-8 编码需要三个字节,即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,从严的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,严的 UTF-8 编码是11100100 10111000 10100101,转换成十六进制就是E4B8A5。
注意
go语言中字符串使用双引号,"测" 是字符串类型,底层保存是用的3个byte保存的。不要和rune(int32)类型的 '测'搞混了。
转义字符
为了处理字符中的特殊字符。在Go语言中,字符常量使用单引号包围,而单引号本身在字符中也有特殊含义,因此需要转义字符来表示这些特殊字符。例如,换行符\n
、制表符\t
、单引号'
和双引号"
等都需要通过转义字符来表示,以确保字符能够正确解析和执行
- \t : 表示一个制表符,通常使用它可以排版
- \n :换行符
- \ :一个\
- " :一个"
- \r :一个回车
- ' :一个'
- \数字 :一个8进制数表示的一个字符(数字需要在8进制的000到377)
字符串
在go语言中,单引号留给了 字符 字面量表达 本质上是int32(rune)类型
所以在go语言中用双引号("
)和反引号(`)来表示字符串字面量。
双引号("
)
- 基本用法:双引号用来定义普通的字符串常量。
- 转义字符 :在双引号定义的字符串中,可以使用转义字符(如
\n
表示换行,\t
表示制表符,\
表示反斜杠本身等)来表示一些特殊字符。 - 多行字符串 :尽管双引号定义的字符串不能直接跨多行,你可以通过在字符串中使用
+
操作符
例如:
s := "这是一个普通的字符串。"
multiLine := "这是第一行。\n这是第二行。"
multiLine2 := "这是第一行。\n" + "这是第二行。"
反引号(```)
- 原始字符串:反引号定义的是原始字符串(raw string),它会将字符串中的所有内容(包括换行符、制表符等)都视为普通字符,不做任何转义处理。
- 多行字符串:反引号非常适合用来定义多行字符串,因为它会保持字符串中的所有格式和换行符不变。
- 正则表达式:在处理正则表达式时,经常使用反引号来定义包含特殊字符的字符串,因为这样可以避免对这些特殊字符进行转义。
rawString := `这是一个
多行字符串。`
regex := `[a-zA-Z\d]+` // 使用反引号定义正则表达式
Go的字符串是不可变的
这意味着一旦创建了字符串,就不能修改它的内容。
str := "Hello"
str[0] = 'h' // 这会导致 编译错误 ,因为str是不可变的。
Sprintf
Sprintf:将格式化后的字符串返回,不输出到控制台。
根据这个特性。我们可以用它来做字符串拼接。和其他类型转为字符串类型
-
字符串拼接:sprintf函数可以将多个变量或常量按照指定的格式拼接为一个字符串
goname := "John" age := 30 height := 1.75 str := fmt.Sprintf("My name is %s, I am %d years old, and my height is %.2f meters.", name, age, height) fmt.Println(str)
-
其他类型转换为字符串类型
go
a := fmt.Sprintf("%d", 100)
b := fmt.Sprintf("%.2f", 123.123)
c := fmt.Sprintf("%t", true)
fmt.Println(a, b, c)
string和数值类型转换
string和数值类型(int、float等等)的转换,需要通过strconv包来进行。
编辑
ParseFloat和ParseInt
func ParseFloat(s string, bitSize int) (float64, error)
s
:要转换的字符串。bitSize
表示浮点数的位大小,通常是32或64。函数的返回值是转换后的浮点数和一个错误类型。如果转换成功,返回的浮点数和nil;如果转换失败,返回的浮点数为0,错误类型不为nil
func ParseInt(s string, base int, bitSize int) (i int64, err error)
s
:要转换的字符串。base
:进制基数,范围从2到36。如果为0,则会根据字符串前缀判断进制(例如,"0x"表示16进制,"0"表示8进制,否则为10进制)。bitSize
:结果必须适合的整数类型,0、8、16、32、64分别对应int
、int8
、int16
、int32
、int64
。如果bitSize
小于0或大于64,将返回错误。
注意:
bitSize
参数指定的是结果必须适合的整数类型,而不是返回的数据类型。无论bitSize
设置为多少,返回的类型始终为int64
。
go
v32 := "-354634382"
if s, err := strconv.ParseInt(v32, 10, 32); err == nil {
fmt.Printf("%T, %v\n", s, s) // 输出: int64, -354634382
} else {
fmt.Println(err)
}
if s, err := strconv.ParseInt(v32, 16, 32); err == nil {
fmt.Printf("%T, %v\n", s, s)
} else {
fmt.Println(err) // 输出: strconv.ParseInt: parsing "-354634382": value out of range
}
if s, err := strconv.ParseInt(v32, 16, 64); err == nil {
fmt.Printf("%T, %v\n", s, s) //int64, -14300693378
} else {
fmt.Println(err)
}
ParseBool()
func ParseBool(str string) (bool, error)
函数用于将字符串转换为 bool 类型的值,它只能接受 1、0、t、f、T、F、true、false、True、False、TRUE、FALSE,其它的值均返回错误。
FormatFloat
Formatxxxxx 函数调用方法以及理解上几乎是一样的,这里拿FormatFloat为例
FormatFloat() 函数用于将浮点数转换为字符串类型,函数签名如下:
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
f
: 要格式化的浮点数。fmt
: 格式标记,可以是'b'(二进制)、'e'(科学计数法)、'f'(十进制无指数)、'g'(最少计数法表示)。prec
: 表示精度,对于'f'和'g'格式,表示除小数点以外的位数。bitSize
: 浮点数类型,32表示float32,64表示float64。
go
var num1 float64 = 3.1415926
var num2 float64 = 12345.6789
var num3 float64 = -9876.54321
// 使用FormatFloat函数将浮点数转为字符串
str1 := strconv.FormatFloat(num1, 'f', 2, 64) // 保留两位小数
str2 := strconv.FormatFloat(num2, 'e', 4, 64) // 使用科学计数法,保留四位小数
str3 := strconv.FormatFloat(num3, 'g', -1, 32) // 自动选择最少计数法表示,适用于float32
// 输出转换结果
fmt.Println("浮点数转换为字符串:")
fmt.Printf("%T:%[1]v\t", str1) //string:3.14
fmt.Printf("%T:%[1]v\t", str2) //string:1.2346e+04
fmt.Printf("%T:%[1]v\t", str3) //string:-9876.543