一、Go语言计算字符串长度

len()
len()
str01 := "Hello World!"
str02 := "你好"
fmt.Println(len(str01))   // 12
fmt.Println(len(str02))   // 6
len()
  • 输出中第一行的 12 表示 tip1 的字符个数为 12。
  • 输出中第二行的 6 表示 str02 的字符格式,也就是"你好"的字符个数是 6,然而根据习惯,"你好"的字符个数应该是 2。

这里的差异是由于 Go 语言的字符串都以 UTF-8 格式保存,每个中文占用 3 个字节,因此使用 len() 获得两个中文文字对应的 6 个字节。

RuneCountInString()

如果希望按习惯上的字符个数来计算,就需要使用 Go 语言中 UTF-8 包提供的 RuneCountInString() 函数,统计 Uncode 字符数量。

下面的代码展示如何计算UTF-8的字符个数。

package mainimport "fmt"
import "unicode/utf8"func main() {str02 := "你好"fmt.Println(len(str02))       // 6fmt.Println(utf8.RuneCountInString(str02))   // 2fmt.Println(utf8.RuneCountInString("你好,world"))  // 8
}

总结:

  • ASCII 字符串长度使用 len() 函数。
  • Unicode 字符串长度使用 utf8.RuneCountInString() 函数。

二、Go语言遍历字符串——获取每一个字符串元素

2.1、遍历每一个ASCII字符

遍历 ASCII 字符使用 for 的数值循环进行遍历,直接取每个字符串的下标获取 ASCII 字符,如下面的例子所示。

package mainimport "fmt"func main() {theme := "狙击 start"for i := 0; i < len(theme); i++ {fmt.Printf("ascii: %c  %d\n", theme[i], theme[i])}
}// 结果如下
ascii: å  229
ascii:   135
ascii: »  187
ascii:    32
ascii: s  115
ascii: t  116
ascii: a  97
ascii: r  114
ascii: t  116

由于没有使用 Unicode,汉字被显示为乱码。

2.2、按Unicode字符遍历字符串

package mainimport "fmt"func main() {theme := "狙击 start"// range 函数用法见参考文档for _, s := range theme {fmt.Printf("Unicode: %c  %d\n", s, s)}
}
// 结果如下
Unicode: 狙  29401
Unicode: 击  20987
Unicode:    32
Unicode: s  115
Unicode: t  116
Unicode: a  97
Unicode: r  114
Unicode: t  116

总结

for range

三、Go语言字符串截取(获取字符串的某一段字符)

获取字符串的某一段字符是开发中常见的操作,我们一般将字符串中的某一段字符称做子串(substring)。

package mainimport "fmt"
import "strings"func main() {full_str := "hello 杰克, I want some help!"son_str_01 := strings.Index(full_str, ", ")fmt.Println(son_str_01)fmt.Println(full_str[son_str_01:])fmt.Println(full_str[son_str_01 + 1:])fmt.Println(full_str[:son_str_01])fmt.Println("=======================")son_str_02 := strings.LastIndex(full_str, "e")fmt.Println(son_str_02)fmt.Println(full_str[son_str_02:])fmt.Println(full_str[son_str_02 + 1:])fmt.Println(full_str[:son_str_02])fmt.Println("=======================")son_str_03 := strings.Index(full_str, "e")fmt.Println(son_str_03)fmt.Println(full_str[son_str_03:])fmt.Println(full_str[son_str_03 + 1:])fmt.Println(full_str[:son_str_03])
}// 结果如下
12
, I want some help!I want some help!
hello 杰克
=======================
27
elp!
lp!
hello 杰克, I want some h
=======================
1
ello 杰克, I want some help!
llo 杰克, I want some help!
h

如上:

strings.Index(full_str, ", ")strings.LastIndex(full_str, "e")

总结

  • 字符串索引比较常用的有如下几种方法:
  • strings.Index:正向搜索子字符串。
  • strings.LastIndex:反向搜索子字符串。
  • 搜索的起始位置可以通过切片偏移制作。
stringBuilder

除了加号连接字符串,Go 语言中也有类似于 StringBuilder 的机制来进行高效的字符串连接,例如:

package mainimport "fmt"
import "bytes"func main() {str01 := "Hello,"str02 := "world!"// 声明字节缓冲var stringBuilder bytes.Buffer// 把字符串写入缓冲stringBuilder.WriteString(str01)stringBuilder.WriteString(str02)// 将缓冲以字符串形式输出fmt.Println(stringBuilder.String())
}// 结果如下:
Hello,world!
bytes.BufferWriteString()
WriteString()stringBuilder.String()

五、Go语言fmt.Sprintf(格式化输出)

格式化在逻辑中非常常用。使用格式化函数,要注意写法:

fmt.Sprintf(格式化样式, 参数列表…)

格式化样式:

  • 字符串形式,格式化动词以%开头。
  • 参数列表:多个参数以逗号分隔,个数必须与格式化样式中的个数一一对应,否则运行时会报错。

字符串格式化时常用动词及功能

动 词功 能
%v按值的本来值输出
%+v在 %v 基础上,对结构体字段名和值进行展开
%#v输出 Go 语言语法格式的值
%T输出 Go 语言语法格式的类型和值
%%输出 % 本体
%b整型以二进制方式显示
%o整型以八进制方式显示
%d整型以十进制方式显示
%x整型以十六进制方式显示
%X整型以十六进制、字母大写方式显示
%UUnicode 字符
%f浮点数
%p指针,十六进制方式显示

如下:

package mainimport "fmt"func main() {a := "你好:hello, world!"b := 18c := 15.4value := fmt.Sprintf("%v",a)fmt.Println(value)    value1 := fmt.Sprintf("%+v",a)fmt.Println(value1)value2 := fmt.Sprintf("%#v",a)fmt.Println(value2)value3 := fmt.Sprintf("%T",a)fmt.Println(value3)value4 := fmt.Sprintf("%%",a)fmt.Println(value4)value5 := fmt.Sprintf("%b",b)fmt.Println(value5)value6 := fmt.Sprintf("%o",b)fmt.Println(value6)value7 := fmt.Sprintf("%d",b)fmt.Println(value7)value8 := fmt.Sprintf("%x",b)fmt.Println(value8)value9 := fmt.Sprintf("%X",b)fmt.Println(value9)value10 := fmt.Sprintf("%U",a)fmt.Println(value10)value11 := fmt.Sprintf("%f",c)fmt.Println(value11)value12 := fmt.Sprintf("%p",c)fmt.Println(value12)value13 := fmt.Sprintf("%p",b)fmt.Println(value13)value14 := fmt.Sprintf("%p",a)fmt.Println(value14)
}
//结果如下:
你好:hello, world!
你好:hello, world!
"你好:hello, world!"
string
%%!(EXTRA string=你好:hello, world!)
10010
22
18
12
12
%!U(string=你好:hello, world!)
15.400000
%!p(float64=15.4)
%!p(int=18)
%!p(string=你好:hello, world!)

参考文档:
1、https://www.laike.net/article-22-8120-0.html