Golang字符串
一个Go语言字符串是一个任意字节的常量序列。[]byte
Go语言字符串字面量
在Go语言种,字符串字面量使用双引号""
或者反引号 ` 来创建。双引号用来创建可解析的字符串,支持转义,但不能用来引用多行;反引号用来创建原生的字符串字面量,可能由多行组成,但不支持转义,并且可以包含除了反引号外其他所有字符。双引号创建可解析的字符串应用最广泛,反引号用来创建原生的字符串则多用于书写多行消息,HTML以及正则表达式。
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package main
import "fmt"
func main() { var str1 string = "hello world" var html string = ` <html> <head><title>hello golang</title> </html> ` fmt.Printf("str1: %v\n", str1) fmt.Printf("html: %v\n", html) }
|
运行结果:
1 2 3 4 5
| str1: hello world html: <html> <head><title>hello golang</title> </html>
|
Go语言字符串连接
使用加号
虽然Go语言忠的字符串事不可变的,但是字符串支持+
级联操作和+=
追加操作,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package main
import "fmt"
func main() { name := "weiyunfeng" age := "23" msg := name + " " + age fmt.Printf("msg %v\n", msg) msg = "" msg += name msg += " " msg += age fmt.Printf("msg %v\n", msg) }
|
运行结果:
1 2
| msg weiyunfeng 23 msg weiyunfeng 23
|
golang里面的字符串都是不可变的,每次运算都会产生一个新的字符串,所以会产生很多临时的无用的字符串,不仅没有用,还会给gc带来额外的负担,所以性能比较差
使用fmt.Sprintf()函数
1 2 3 4 5 6 7 8 9 10
| package main
import "fmt"
func main() { name := "weiyunfeng" age := "23" msg := fmt.Sprintf("name=%s,age=%s", name, age) fmt.Printf("msg: %v\n", msg) }
|
运行结果:
1
| msg: name=weiyunfeng,age=23
|
内部使用[]byte实现,不像直接运算符这种会产生很多临时的字符串,但是内部逻辑比较复杂,有很多额外的判断,还用到了interface,所以性能也不是很好
strings.Join()
1 2 3 4 5 6 7 8 9 10 11 12 13
| package main
import ( "fmt" "strings" )
func main() { name := "weiyunfeng" age := "23" msg := strings.Join([]string{name, age}, ",") fmt.Printf("msg: %v\n", msg) }
|
运行结果:
join会先根据字符串数组的内容,计算出一个拼接之后的长度,然后申请对应大小的内存,一个一个字符串填入,在已有一个数组的情况下,这种效率会很高,但是本来没有,去构造这个数据的代价也不小
buffer.WriteString()
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package main
import ( "bytes" "fmt" )
func main() { var buffer bytes.Buffer buffer.WriteString("weiyunfeng") buffer.WriteString(",") buffer.WriteString("23") fmt.Printf("buffer.string(): %v\n", buffer.String()) }
|
这个比较理想,可以当成可变字符串使用,对内存的增长也有优化,如果能预估字符串的长度,还可以用buffer.Grow()接口来设置capacity
Go语言字符串转义字符
Go语言的字符串常见转义符包含回车、换行、双引号、制表符等,如下表所示。
注意Golang里面不存在单引号用反斜杠转义,单引号就直接打印就行
转义符 |
含义 |
\r |
回车符(返回行首) |
\n |
换行符(直接跳到下一行的同列位置) |
\t |
制表符 |
\" |
双引号 |
\\ |
反斜杠 |
实例
1 2 3 4 5 6 7 8 9 10
| package main
import ( "fmt" )
func main() { fmt.Print("Hello\tWorld\n") fmt.Print("\"c:\\test\\\"") }
|
运行结果:
Go语言字符串切片操作
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package main
import ( "fmt" )
func main() { str := "weiyunfeng world" n := 3 m := 5 fmt.Printf("s[a]: %c\n", str[n]) fmt.Printf("s[a]: %v\n", str[n:m]) fmt.Printf("s[a]: %v\n", str[n:]) fmt.Printf("s[a]: %v\n", str[:m]) }
|
运行结果:
1 2 3 4
| s[a]: y s[a]: yu s[a]: yunfeng world s[a]: weiyu
|
Go语言字符串常用方法
方法 |
介绍 |
len(str) |
求长度 |
+或fmt.Sprintf |
拼接字符串 |
strings.Split |
分割 |
strings.contains |
判断是否包含 |
strings.HasPrefix,strings.HasSuffix |
前缀/后缀判断 |
strings.Index(),strings.LastIndex() |
子串出现的位置 |
strings.Join(a[]string,sep string) |
join操作 |
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package main
import ( "fmt" "strings" )
func main() { s := "weiyunfeng WoRld" fmt.Printf("len(s): %v\n", len(s)) fmt.Printf("strings.Split(s, \" \"): %v\n", strings.Split(s, " ")) fmt.Printf("strings.Contains(s, \"weiyunfeng\"): %v\n", strings.Contains(s, "weiyunfeng")) fmt.Printf("strings.ToLower(s): %v\n", strings.ToLower(s)) fmt.Printf("strings.ToUpper(s): %v\n", strings.ToUpper(s))
fmt.Printf("strings.HasPrefix(s,\"weiyunfeng\"): %v\n", strings.HasPrefix(s, "weiyunfeng")) fmt.Printf("strings.HasSuffix(s, \"WoRld\"): %v\n", strings.HasSuffix(s, "WoRld"))
fmt.Printf("strings.Index(s, \"y\"): %v\n", strings.Index(s, "y"))
a := []string{"wo", "shi", "weiyunfeng"} fmt.Printf("strings.Join(a, \",\"): %v\n", strings.Join(a, ",")) }
|
运行结果:
1 2 3 4 5 6 7 8 9
| len(s): 16 strings.Split(s, " "): [weiyunfeng WoRld] strings.Contains(s, "weiyunfeng"): true strings.ToLower(s): weiyunfeng world strings.ToUpper(s): WEIYUNFENG WORLD strings.HasPrefix(s,"weiyunfeng"): true strings.HasSuffix(s, "WoRld"): true strings.Index(s, "y"): 3 strings.Join(a, ","): wo,shi,weiyunfeng
|