go语言字符串

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语言中用双引号(")和反引号(`)来表示字符串字面量。

双引号("

  1. 基本用法:双引号用来定义普通的字符串常量。
  2. 转义字符 :在双引号定义的字符串中,可以使用转义字符(如\n表示换行,\t表示制表符,\表示反斜杠本身等)来表示一些特殊字符。
  3. 多行字符串 :尽管双引号定义的字符串不能直接跨多行,你可以通过在字符串中使用+操作符

例如:

s := "这是一个普通的字符串。"

multiLine := "这是第一行。\n这是第二行。"

multiLine2 := "这是第一行。\n" + "这是第二行。"

反引号(```)

  1. 原始字符串:反引号定义的是原始字符串(raw string),它会将字符串中的所有内容(包括换行符、制表符等)都视为普通字符,不做任何转义处理。
  2. 多行字符串:反引号非常适合用来定义多行字符串,因为它会保持字符串中的所有格式和换行符不变。
  3. 正则表达式:在处理正则表达式时,经常使用反引号来定义包含特殊字符的字符串,因为这样可以避免对这些特殊字符进行转义。

rawString := `这是一个

多行字符串。`

regex := `[a-zA-Z\d]+` // 使用反引号定义正则表达式

Go的字符串是不可变的

这意味着一旦创建了字符串,就不能修改它的内容。

str := "Hello"

str[0] = 'h' // 这会导致 编译错误 ,因为str是不可变的。

Sprintf

Sprintf:将格式化后的字符串返回,不输出到控制台。

根据这个特性。我们可以用它来做字符串拼接。和其他类型转为字符串类型

  • 字符串拼接:sprintf函数可以将多个变量或常量按照指定的格式拼接为一个字符串

    go 复制代码
    name := "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分别对应intint8int16int32int64。如果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

相关推荐
研究司马懿1 天前
【云原生】Gateway API高级功能
云原生·go·gateway·k8s·gateway api
梦想很大很大1 天前
使用 Go + Gin + Fx 构建工程化后端服务模板(gin-app 实践)
前端·后端·go
lekami_兰2 天前
MySQL 长事务:藏在业务里的性能 “隐形杀手”
数据库·mysql·go·长事务
却尘2 天前
一篇小白也能看懂的 Go 字符串拼接 & Builder & cap 全家桶
后端·go
ん贤2 天前
一次批量删除引发的死锁,最终我选择不加锁
数据库·安全·go·死锁
mtngt112 天前
AI DDD重构实践
go
Grassto4 天前
12 go.sum 是如何保证依赖安全的?校验机制源码解析
安全·golang·go·哈希算法·go module
Grassto6 天前
11 Go Module 缓存机制详解
开发语言·缓存·golang·go·go module
程序设计实验室7 天前
2025年的最后一天,分享我使用go语言开发的电子书转换工具网站
go
我的golang之路果然有问题7 天前
使用 Hugo + GitHub Pages + PaperMod 主题 + Obsidian 搭建开发博客
golang·go·github·博客·个人开发·个人博客·hugo