golang5字符串
字符串
格式化输出
摘要
该视频主要讲述了Go语言中格式化输出的重要性及其实现方式。首先强调了格式化输出的常用性和记忆关键点的重要性。随后,通过对比传统字符串拼接与格式化输出的方式,展示了后者在复杂输出场景下的优势,如简化代码、提高可读性和可维护性,同时避免了类型转换的麻烦。最后,指出了格式化输出在性能要求极高的场景下可能不是最佳选择。
分段总结
折叠
00:03Go语言格式化输出介绍
1.格式化输出在Go语言中非常常用,用于将变量格式化为字符串进行输出。 2.可以通过字符串拼接和转义符进行简单的输出,但对于复杂数据结构,这种方法可读性和维护性较差。
04:18Go语言格式化输出重要性
1.格式化输出在Go语言中的重要性,强调了正确和高效性。 2.推荐使用格式化输出,提高代码可读性和可维护性。 3.性能考虑,性能要求高的场景应避免使用格式化输出。 4.格式化输出的使用场景和限制。
06:12Go语言中的打印输出与字符串生成
1.打印输出时,格式化输出,字符串生成方法。 2.性能考虑选择合适的数据生成方法。
07:40Go语言输出函数的应用
1.输出函数的应用,不同输出函数的用途和选择方法。
一、Go语言格式化输出 00:01
1. 字符串拼接 00:44
基本方法:使用"+"运算符拼接字符串,如"hello " + username
缺点
:
当需要拼接多个变量时(如用户名、年龄、地址等),代码会变得冗长复杂
需要进行类型转换(如将int类型的age转换为string)
可读性和可维护性差,容易出错
2. 格式化输出 04:24
1)Printf
语法:fmt.Printf("模板字符串", 参数...)
特点
:
使用占位符(如%s、%d)在模板中指定变量位置
不需要手动进行类型转换
代码更简洁易读
常用占位符
:
%s:字符串
%d:整数
%f:浮点数
注意:Printf不会自动添加换行符,需要手动添加\r\n
2)Sprintf 06:30
功能:将格式化后的字符串作为返回值,而不是直接输出
语法:str := fmt.Sprintf("模板字符串", 参数...)
与Printf区别
:
Printf直接输出到标准输出
Sprintf返回格式化后的字符串
应用场景:需要将格式化结果保存到变量中时使用
3)性能问题 06:03
性能比较:字符串拼接的性能优于格式化输出
建议
:
在性能要求高的场景下尽量使用字符串拼接
其他情况下推荐使用格式化输出,因为可读性和可维护性更好
3. 输出格式化 07:57
1)缺省格式和类型 08:04
缺省格式
08:13
%v
:以默认格式输出值
对于字符串,与%s效果相同
对于slice等复杂类型,会输出其内容
类型打印
09:27
%T
:输出值的类型
如[]int、int等
不关心具体值,只显示类型信息
Go语法打印
%#v
:以Go语法格式输出值
会显示类型信息和字面值
如[]int{1,2,3}
整型格式化
10:36
%d:十进制
%+d:强制显示正负号
%4d:宽度为4,右对齐,左边补空格
%-4d:宽度为4,左对齐,右边补空格
%b:二进制
%o:八进制
%x:十六进制(小写)
字符格式化
11:21
%c:输出Unicode字符
%q:带引号的字符
%U:Unicode格式
浮点数格式化
11:34
%f:十进制小数
%e:科学计数法
字符串格式化
%s:原样输出字符串
%6s:宽度为6,右对齐
%-6s:宽度为6,左对齐
2)总结 11:49
常用占位符:%v、%T、%d、%s、%f
选择原则:根据输出需求选择合适的格式化选项
文档参考:其他不常用的选项可以在需要时查阅文档
二、知识小结
知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
---|---|---|---|
Go语言格式化输出 | 讲解fmt.Printf和fmt.Sprintf的使用方法及区别 | 字符串拼接 vs 格式化输出的性能差异 | ⭐⭐ |
格式化动词 | 介绍%s(字符串)、%d(整数)、%v(通用值)、%t(类型)等常用占位符 | %v与%#v的输出格式区别 | ⭐⭐⭐ |
对齐控制 | 数字格式化中的宽度控制(%4d)和对齐方式(%-4d) | 正负号显示(%+d)和补零(%04d)的区别 | ⭐⭐⭐⭐ |
类型转换 | 演示字符串拼接时的手动类型转换(strconv.Itoa) | 自动类型转换在格式化输出中的优势 | ⭐⭐ |
特殊格式 | 二进制(%b)、八进制(%o)、Unicode(%U)等特殊输出格式 | 字符(%c)与带引号字符(%q)的区别 | ⭐⭐⭐ |
性能考量 | 强调格式化输出代码可维护性与运行时性能的权衡 | 高性能场景应避免使用Sprintf | ⭐⭐⭐⭐ |
字符串拼接
一、字符串拼接 00:00
1. 使用Sprintf 00:13
基本用法:通过fmt.Sprintf函数实现格式化字符串拼接,语法为fmt.Sprintf(format string, a ...any) string
格式化符号
:
%s:字符串类型
%d:整数类型
%T:变量类型
特点
:
代码可读性强,维护方便
性能较差,不适合高频调用场景
常用但非高性能选择
示例:
2. 使用StringBuilder 00:27
1)示例 03:11
高性能拼接:通过strings.Builder实现字符串高效拼接
核心方法
:
WriteString():追加字符串内容
String():获取最终拼接结果
性能特点
:
性能远高于+拼接和Sprintf
适合高频调用和性能敏感场景
代码可读性较差但执行效率高
使用步骤
:
导入strings包
声明var builder strings.Builder
通过WriteString方法连续写入
调用String()获取结果
完整示例:
2)方法对比
性能排序:StringBuilder > +拼接 > Sprintf
选择原则
:
性能要求高时选择StringBuilder
开发效率优先时选择Sprintf
避免在循环中使用+拼接
典型场景
:
日志输出:使用Sprintf
高频字符串处理:使用StringBuilder
二、知识小结
知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
---|---|---|---|
字符串拼接方法 | 三种字符串拼接方式:1. 加号拼接2. sprintf格式化拼接3. String Builder高性能拼接 | 性能对比:- 加号:中等性能- sprintf:最差性能但易用- String Builder:最高性能但代码复杂 | ⭐⭐ |
String Builder使用 | 关键步骤:1. 导入strings包2. 声明Builder对象3. 使用WriteString方法连续写入4. 调用String()方法获取结果 | 易错点:- 忘记导入strings包- 未正确处理多数据类型写入(需区分WriteString/WriteByte) | ⭐⭐⭐ |
方法选择策略 | 应用场景决策树:- 性能敏感场景 → 强制使用String Builder- 常规场景 → 优先选择sprintf | 关键结论:性能差异显著,需根据场景严格选择 | ⭐⭐ |
字符串比较
一、字符串的其他常用需求 00:01
1. 字符串的比较 00:08
1)字符串等于不等于的比较 00:26
比较运算符:使用==判断相等,!=判断不等,与其他语言语法一致
示例说明
:
当
a="hello"a="hello"a="hello"
,
b="hello"b="hello"b="hello"
时,
a==ba==ba==b
结果为true
相同条件下
a!=ba!=ba!=b
结果为false,IDE会提示"expression is always false"
语法细节
:注意比较运算符需要写两个等号/叹号,如
a==ba==ba==b
不能写成
a=ba=ba=b
底层原理:比较的是字符串的Unicode码点值序列
特殊说明:即使未学习if语句,也可以直接通过fmt.Println输出比较结果
2)字符串的大小比较 01:21
比较规则
:
从左到右逐个字符比较ASCII/Unicode码点值
第一个不同字符的码点值决定整体大小关系
典型示例
:
当
a="ha..any"a="ha..any"a="ha..any"
,
b="hettu"b="hettu"b="hettu"
时
比较过程:先比较'h'和'h'(相等),然后比较'a'和'e'(97<101)
最终结果:
a<ba<ba<b
为true
应用场景:可用于字符串排序、字典序比较等操作
注意事项:大小写字母的码点值不同('A'=65,'a'=97),比较时区分大小写
二、知识小结
知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
---|---|---|---|
字符串比较 | 使用==和!=进行等于/不等于比较,基于字符的ASCII码逐位对比 | 注意双等号==的使用(与其他语言一致) | ⭐⭐ |
字符串大小比较 | 通过>或<比较字符串大小,规则为从左到右逐字符对比ASCII码值 | "hello" > "bello"因'h'的ASCII码大于'b' | ⭐⭐ |
比较依据 | 字符本质为ASCII码(int类型),比较时转换为数值对比 | 易忽略非字母字符(如数字、符号)的ASCII码差异 | ⭐⭐ |
字符串常用方法
摘要
本视频主要讲解了字符串操作的一些常用方法,涵盖了字符串的包含判断、长度计算、切片操作、分割、查询子串出现次数等。介绍了字符串大小写转换、替换、修剪特定字符的方法,并演示了如何使用这些方法处理字符串。同时,也介绍了如何通过查看源码来了解字符串包中更多的方法。视频还强调了在实际应用中需要注意的细节,如字符串分割时的兼容性问题,以及替换操作中参数的合理使用。最后,提到了通过源码查看可以了解更多字符串处理方法,并预告了下节将介绍Go语言中的if和for循环。
分段总结
折叠
00:01字符串常用方法概述
1.字符串常用方法主要在strings包中。 2.import strings时,必须明确导入使用的包,否则编译器会提示错误。 3.可以通过查看源码来了解strings包中所有的方法,包括join、index、repeat、split、title、lower、trim等。
01:51常用方法之是否包含
1.contains方法用于检查一个字符串是否包含指定的子串。 2.该方法返回一个布尔值,表示是否包含子串。 3.示例:检查字符串name是否包含子串"mock",结果为true。
03:06常用方法之字符串长度
1.len函数用于获取字符串的长度。 2.示例:通过len函数获取字符串name的长度。
03:30常用方法之查询子串出现次数
1.count方法用于查询子串在字符串中出现的次数。 2.示例:查询字符串name中"o"出现的次数,结果为3。
04:14常用方法之字符串分割
1.split方法用于将字符串按照指定的分隔符进行分割。 2.示例:通过split方法将字符串name按照短横线"-"进行分割,得到两个部分。
05:25常用方法之字符串前缀和后缀检查
1.hasPrefix方法用于检查字符串是否以指定的前缀开头。 2.hasSuffix方法用于检查字符串是否以指定的后缀结尾。 3.示例:检查字符串name是否以"I"或"imook"开头,是否以"engineer"结尾。
06:55常用方法之查询子串出现位置
1.index方法用于查询子串在字符串中第一次出现的位置。 2.示例:查询字符串name中"go"出现的位置,结果为14。
09:28常用方法之字符串替换
1.replace方法用于将字符串中的旧子串替换为新子串。 2.示例:将字符串name中的"go"替换为"JAVA",结果为"I mock JAVA engineer"。
11:04常用方法之大小写转换
1.lower方法用于将字符串中的大写字母转换为小写字母。 2.upper方法用于将字符串中的小写字母转换为大写字母。 3.示例:将字符串name中的"go"转换为小写,结果为"go"。
12:05常用方法之去除字符串两边的特殊字符
1.trim方法用于去除字符串两边的指定字符。 2.trimLeft方法用于去除字符串左边的指定字符。 3.trimRight方法用于去除字符串右边的指定字符。 4.示例:去除字符串hello中的空格,结果为"hello"。
一、字符串常用方法 00:01
1. 导入strings包 00:16
导入方式: 使用括号将多个import包分组,使代码更美观
注意事项: 导入的包必须被使用,否则会提示"Unused import"错误
2. 字符串操作 01:02
1)字符串包含 02:04
Contains方法: 检查字符串是否包含子串,返回布尔值
示例: strings.Contains("imooc体系课-go工程师", "go") 返回 true
源码查看: 可通过IDE直接查看strings包源码了解所有可用方法
2)子串计数 03:33
Count方法: 统计子串出现次数
示例: strings.Count("imooc体系课-go工程师", "o") 返回 3
3)字符串分割 04:14
Split方法: 按分隔符分割字符串,返回切片
示例: strings.Split("imooc体系课-go工程师", "-") 返回 ["imooc体系课", "go工程师"]
特性: 当分隔符不存在时,返回包含原字符串的切片
4)前后缀检查 05:26
HasPrefix: 检查字符串是否以指定前缀开头
示例: strings.HasPrefix("imooc体系课", "imooc") 返回 true
HasSuffix: 检查字符串是否以指定后缀结尾
示例: strings.HasSuffix("go工程师", "工程师") 返回 true
5)子串位置查找 06:57
Index方法: 返回子串首次出现的字节索引位置
示例: strings.Index("imooc体系课go工程师", "go") 返回 14
注意: 中文处理需谨慎,返回的是字节位置而非字符位置
6)字符串替换 09:28
Replace方法: 替换字符串中的子串
参数说明
:
old: 被替换的子串
new: 新子串
n: 替换次数,负数表示全部替换
示例: strings.Replace("go工程师go", "go", "java", 1) 只替换第一个"go"
7)大小写转换 11:01
ToLower: 转换为小写
示例: strings.ToLower("GO") 返回 "go"
ToUpper: 转换为大写
示例: strings.ToUpper("java") 返回 "JAVA"
8)去除特殊字符 11:53
Trim方法: 去除字符串两端的指定字符
示例: strings.Trim("#$hello#", "#$") 返回 "hello"
变体方法
:
TrimLeft: 只去除左侧字符
TrimRight: 只去除右侧字符
二、结束 14:17
三、知识小结
知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
---|---|---|---|
字符串包导入 | 需同时导入fmt和strings包,推荐使用括号分组写法 | 未使用的导入包会导致编译错误 | ⭐ |
字符串包含检测 | strings.Contains()方法判断子串是否存在 | 返回值是布尔类型而非位置索引 | ⭐⭐ |
子串出现次数统计 | strings.Count()统计特定子串出现频率 | 空子串会返回原字符串长度+1 | ⭐⭐ |
字符串分割 | strings.Split()按分隔符切分字符串 | 无匹配分隔符时返回原字符串切片 | ⭐⭐ |
前后缀检测 | HasPrefix()检查开头/HasSuffix()检查结尾 | 函数命名和参数顺序易混淆 | ⭐⭐⭐ |
子串位置查询 | Index()返回字节位置而非字符位置 | 中文等多字节字符需特殊处理 | ⭐⭐⭐⭐ |
字符串替换 | Replace()支持部分替换(n>0)或全部替换(n<0) | 替换计数参数n的边界条件 | ⭐⭐⭐ |
大小写转换 | ToLower()/ToUpper()实现大小写转换 | 仅支持ASCII字符集 | ⭐⭐ |
特殊字符修剪 | Trim()可移除两侧指定字符集合 | 仅处理两端字符不处理中间内容 | ⭐⭐⭐ |
源码查阅技巧 | 使用Ctrl+O查看包内所有方法 | 需区分导出方法(首字母大写)和内部方法 | ⭐ |
Go 语言的 strings
包
提供了丰富的字符串操作函数,涵盖了字符串的查找、替换、分割、连接、转换等常见功能。以下是对 strings
包核心方法的详细讲解,包含代码示例和注释说明:
一、字符串查找相关方法
用于在字符串中查找子串的位置或判断是否包含子串。
1. Contains(s, substr string) bool
判断字符串 s
是否包含子串 substr
。
go
package mainimport ("fmt""strings" )func main() {s := "hello world"sub := "world"// 判断 s 是否包含 subfmt.Println(strings.Contains(s, sub)) // 输出: truefmt.Println(strings.Contains(s, "go")) // 输出: false }
2. ContainsAny(s, chars string) bool
判断字符串 s
是否包含 chars
中的任意一个字符。
go
func main() {s := "hello"// 判断 s 是否包含 'a' 或 'b' 或 'e'fmt.Println(strings.ContainsAny(s, "abe")) // 输出: true(包含 'e')fmt.Println(strings.ContainsAny(s, "xyz")) // 输出: false }
3. Index(s, substr string) int
返回子串 substr
在 s
中第一次出现的索引,若不存在则返回 -1
。
go
func main() {s := "hello world"// 查找 "lo" 在 s 中的首次出现位置fmt.Println(strings.Index(s, "lo")) // 输出: 3(索引从 0 开始)fmt.Println(strings.Index(s, "go")) // 输出: -1(不存在) }
4. LastIndex(s, substr string) int
返回子串 substr
在 s
中最后一次出现的索引,若不存在则返回 -1
。
go
func main() {s := "ababa"// 查找 "aba" 在 s 中最后一次出现的位置fmt.Println(strings.LastIndex(s, "aba")) // 输出: 2("aba" 从索引 2 开始:"aba"[2:5]) }
二、字符串替换相关方法
用于替换字符串中的子串。
1. Replace(s, old, new string, n int) string
将 s
中前 n
个 old
子串替换为 new
,n < 0
表示替换所有。
go
func main() {s := "hello hello hello"// 替换前 2 个 "hello" 为 "hi"fmt.Println(strings.Replace(s, "hello", "hi", 2)) // 输出: hi hi hello// 替换所有 "hello" 为 "hi"(n = -1)fmt.Println(strings.Replace(s, "hello", "hi", -1)) // 输出: hi hi hi }
2. ReplaceAll(s, old, new string) string
替换 s
中所有 old
子串为 new
(等价于 Replace(s, old, new, -1)
)。
go
func main() {s := "go is good, go is great"// 替换所有 "go" 为 "Golang"fmt.Println(strings.ReplaceAll(s, "go", "Golang")) // 输出: Golang is good, Golang is great }
三、字符串分割与连接
用于将字符串分割为切片或拼接切片为字符串。
1. Split(s, sep string) []string
以 sep
为分隔符将 s
分割为切片,若 sep
为空则按字符分割。
go
func main() {s := "a,b,c,d"// 以 "," 分割字符串fmt.Println(strings.Split(s, ",")) // 输出: [a b c d]// 特殊情况:sep 为空时,按单个字符分割fmt.Println(strings.Split("hello", "")) // 输出: [h e l l o] }
2. SplitN(s, sep string, n int) []string
以 sep
为分隔符分割 s
,最多分割为 n
个元素(n < 0
表示不限制)。
go
func main() {s := "a,b,c,d"// 最多分割为 2 个元素fmt.Println(strings.SplitN(s, ",", 2)) // 输出: [a b,c,d] }
3. Join(a []string, sep string) string
将字符串切片 a
以 sep
为分隔符拼接为一个字符串。
go
func main() {parts := []string{"hello", "world", "go"}// 用 " " 拼接切片元素fmt.Println(strings.Join(parts, " ")) // 输出: hello world go// 用 "," 拼接fmt.Println(strings.Join(parts, ",")) // 输出: hello,world,go }
四、字符串转换相关方法
用于字符串的大小写转换、修剪等。
1. ToUpper(s string) string
/ ToLower(s string) string
将字符串转换为全大写 / 全小写。
go
func main() {s := "Hello World"fmt.Println(strings.ToUpper(s)) // 输出: HELLO WORLDfmt.Println(strings.ToLower(s)) // 输出: hello world }
2. Trim(s, cutset string) string
移除 s
首尾所有包含在 cutset
中的字符。
go
func main() {s := " hello world! "// 移除首尾的空格(cutset 为 " ")fmt.Println(strings.Trim(s, " ")) // 输出: hello world!// 移除首尾的 "h"、"d"、"!"s2 := "hdhello!d"fmt.Println(strings.Trim(s2, "hd!")) // 输出: ello }
3. TrimSpace(s string) string
移除 s
首尾的空白字符(空格、制表符 \t
、换行符 \n
等)。
go
func main() {s := "\t\n hello \tworld \n"// 移除首尾空白字符fmt.Println(strings.TrimSpace(s)) // 输出: hello world(中间的制表符保留) }
五、前缀与后缀判断
1. HasPrefix(s, prefix string) bool
判断 s
是否以 prefix
为前缀。
go
func main() {s := "http://example.com"fmt.Println(strings.HasPrefix(s, "http")) // 输出: truefmt.Println(strings.HasPrefix(s, "https")) // 输出: false }
2. HasSuffix(s, suffix string) bool
判断 s
是否以 suffix
为后缀。
go
func main() {s := "example.txt"fmt.Println(strings.HasSuffix(s, ".txt")) // 输出: truefmt.Println(strings.HasSuffix(s, ".md")) // 输出: false }
六、其他实用方法
1. Repeat(s string, count int) string
将 s
重复 count
次并返回新字符串(count <= 0
时返回空字符串)。
go
func main() {fmt.Println(strings.Repeat("ab", 3)) // 输出: abababfmt.Println(strings.Repeat("x", 0)) // 输出: (空字符串) }
2. Count(s, substr string) int
统计 substr
在 s
中出现的非重叠次数。
go
func main() {s := "ababa"fmt.Println(strings.Count(s, "aba")) // 输出: 1("aba" 只在索引 0 出现一次,索引 2 开始是 "aba" 但与前重叠)fmt.Println(strings.Count(s, "ab")) // 输出: 2("ab" 在索引 0 和 2 各出现一次) }
总结
strings
包是 Go 中处理字符串的核心工具,上述方法覆盖了大部分日常开发需求。关键注意点:
所有方法均返回新字符串,原字符串不会被修改(Go 字符串是不可变的)。
方法参数中的
sep
、cutset
等若为空字符串,可能有特殊行为(如Split
按字符分割)。索引相关方法返回
-1
表示未找到,需注意判断避免数组越界。
实际开发中,可结合具体场景选择合适的方法,例如:处理 URL 时用 HasPrefix
判断协议,处理 CSV 时用 Split
分割字段,格式化输出时用 ToUpper
/ToLower
统一大小写等。