关键词:
一个Go语言字符串是一个任意字节的常量序列。[] byte
go语言字符串字面量
在Go语言中,字符串字面量使用双引号 "" 或者反引号 ' 来创建。双引号用来创建可解析的字符串,支持转义,但不能用来引用多行;反引号用来创建原生的字符串字面量,可能由多行组成,但不支持转义,并且可以包含除了反引号外其他所有字符。双引号创建可解析的字符串应用最广泛,反引号用来创建原生的字符串则多用于书写多行消息,HTML以及正则表达式。
实例
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)
运行结果
[Running] go run "/Users/guoliang/Desktop/test.go"
str1: hello world
html:
<html>
<head><title>hello golang</title>
</html>
go语言字符串连接
使用加号
虽然Go语言中的字符串是不可变的,但是字符串支持 + 级联操作和+=追加操作,例如:
package main
import "fmt"
func main()
name := "tom"
age := "20"
msg := name + " " + age
fmt.Printf("msg: %v\\n", msg)
fmt.Println("-------------")
msg = ""
msg += name
msg += " "
msg += age
fmt.Printf("msg: %v\\n", msg)
运行结果
[Running] go run "/Users/guoliang/Desktop/test.go"
msg: tom 20
-------------
msg: tom 20
golang 里面的字符串都是不可变的,每次运算都会产生一个新的字符串,所以会产生很多临时的无用的字符串,不仅没有用,还会给 gc 带来额外的负担,所以性能比较差
使用fmt.Sprintf()函数
package main
import "fmt"
func main()
name := "tom"
age := "20"
msg := fmt.Sprintf("%s,%s", name, age)
fmt.Printf("msg: %v\\n", msg)
运行结果
[Running] go run "/Users/guoliang/Desktop/test.go"
msg: tom,20
内部使用 []byte 实现,不像直接运算符这种会产生很多临时的字符串,但是内部的逻辑比较复杂,有很多额外的判断,还用到了 interface,所以性能也不是很好
strings.Join()
package main
import (
"fmt"
"strings"
)
func main()
name := "tom"
age := "20"
msg := strings.Join([]stringname, age, ",")
fmt.Printf("msg: %v\\n", msg)
运行结果
[Running] go run "/Users/guoliang/Desktop/test.go"
msg: tom,20
join会先根据字符串数组的内容,计算出一个拼接之后的长度,然后申请对应大小的内存,一个一个字符串填入,在已有一个数组的情况下,这种效率会很高,但是本来没有,去构造这个数据的代价也不小
buffer.WriteString()
package main
import (
"bytes"
"fmt"
)
func main()
var buffer bytes.Buffer
buffer.WriteString("tom")
buffer.WriteString(",")
buffer.WriteString("20")
fmt.Printf("buffer.String(): %v\\n", buffer.String())
运行结果
[Running] go run "/Users/guoliang/Desktop/test.go"
buffer.String(): tom,20
这个比较理想,可以当成可变字符使用,对内存的增长也有优化,如果能预估字符串的长度,还可以用 buffer.Grow() 接口来设置 capacity
go语言字符串转义字符
Go 语言的字符串常见转义符包含回车、换行、单双引号、制表符等,如下表所示。
转义符 | 含义 |
\\r | 回车符(返回行首) |
\\n | 换行符(直接跳到下一行的同列位置) |
\\t | 制表符 |
\\' | 单引号 |
\\" | 双引号 |
\\\\ | 反斜杠 |
实例
package main
import (
"fmt"
)
func main()
fmt.Print("hello\\tworld\\n")
fmt.Print("\\"c:\\\\test\\\\\\"")
运行结果
[Running] go run "/Users/guoliang/Desktop/test.go"
hello world
"c:\\test\\"
go语言字符串切片操作
package main
import (
"fmt"
)
func main()
str := "hello world"
n := 3
m := 5
fmt.Println(str[n]) //获取字符串索引位置为n的原始字节
fmt.Println(str[n:m]) //截取得字符串索引位置为 n 到 m-1 的字符串
fmt.Println(str[n:]) //截取得字符串索引位置为 n 到 len(s)-1 的字符串
fmt.Println(str[:m]) //截取得字符串索引位置为 0 到 m-1 的字符串
运行结果
[Running] go run "/Users/guoliang/Desktop/test.go"
108
lo
lo world
hello
go语言字符串常用方法
方法 | 介绍 |
len(str) | 求长度 |
+或fmt.Sprintf | 拼接字符串 |
strings.Split | 分割 |
strings.contains | 判断是否包含 |
strings.HasPrefix,strings.HasSuffix | 前缀/后缀判断 |
strings.Index(),strings.LastIndex() | 子串出现的位置 |
strings.Join(a[]string, sep string) | join操作 |
实例
package main
import (
"fmt"
"strings"
)
func main()
s := "hello world!"
fmt.Printf("len(s): %v\\n", len(s))
fmt.Printf("strings.Split(s, \\" \\"): %v\\n", strings.Split(s, " "))
fmt.Printf("strings.Contains(s, \\"hello\\"): %v\\n", strings.Contains(s, "hello"))
fmt.Printf("strings.HasPrefix(s, \\"hello\\"): %v\\n", strings.HasPrefix(s, "hello"))
fmt.Printf("strings.HasSuffix(s, \\"world!\\"): %v\\n", strings.HasSuffix(s, "world!"))
fmt.Printf("strings.Index(s, \\"l\\"): %v\\n", strings.Index(s, "l"))
fmt.Printf("strings.LastIndex(s, \\"l\\"): %v\\n", strings.LastIndex(s, "l"))
运行结果
[Running] go run "/Users/guoliang/Desktop/test.go"
len(s): 14
strings.Split(s, " "): [hello world!]
strings.Contains(s, "hello"): true
strings.HasPrefix(s, "hello"): true
strings.HasSuffix(s, "world!"): true
strings.Index(s, "l"): 2
strings.LastIndex(s, "l"): 9
byte和rune类型
组成每个字符串的元素叫做“字符”,可以通过遍历或者单个获取字符串元素获得字符。 字符用单引号(’)包裹起来,如:
package main
import "fmt"
func main()
var a = '华'
var b = 'a'
fmt.Printf("a: %v,%c\\n", a, a)
fmt.Printf("b: %v,%c\\n", b, b)
运行结果
[Running] go run "/Users/guoliang/Desktop/test.go"
a: 21326,华
b: 97,a
Go 语言的字符有以下两种:
- uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。
- rune类型,代表一个 UTF-8字符。
当需要处理中文、日文或者其他复合字符时,则需要用到rune类型。rune类型实际是一个int32。
Go 使用了特殊的 rune 类型来处理 Unicode,让基于 Unicode 的文本处理更为方便,也可以使用 byte 型进行默认字符串处理,性能和扩展性都有照顾。
golang入门到项目实战golang匿名函数
参考技术Ago语言函数不能嵌套,但是在函数内部可以定义匿名函数,实现一下简单功能调用。所谓匿名函数就是,没有名称的函数。语法格式如下:当然可以既没有参数,可以没有返回值运行结果自己执行运行结果 查看详情
golang入门到项目实战golang并发编程之runtime包
参考技术Aruntime包里面定义了一些协程管理相关的api让出CPU时间片,重新等待安排任务运行结果退出当前协程运行结果运行结果如果修改最大核心数为1,运行结果如下,不会出现交替执行现象 查看详情
golang入门到项目实战golang结构体指针
参考技术A结构体指针和普通的变量指针相同,我先来回顾一下普通变量的指针,例如:运行结果实例运行结果我们还可以通过使用new关键字对结构体进行实例化,得到的是结构体的地址,例如:运行结果从运行结果,我们发现p_... 查看详情
golang入门到项目实战|golang继承(代码片段)
golang本质上没有oop的概念,也没有继承的概念,但是可以通过结构体嵌套实现这个特性。例如packagemainimport"fmt"typeAnimalstructnamestringageintfunc(aAnimal)eat()fmt.Println("eat...")func(aAnimal)sleep()fmt.Println("sleep")typeDogstr... 查看详情
golang入门到项目实战|golang函数(代码片段)
golang函数简介函数的go语言中的一级公民,我们把所有的功能单元都定义在函数中,可以重复使用。函数包含函数的名称、参数列表和返回值类型,这些构成了函数的签名(signature)。go语言中函数特性go语言... 查看详情
golang入门到项目实战|golang指向数组的指针(代码片段)
定义语法varptr[MAX]*int;表示数据里面的元素的类型是指针类型实例演示packagemainimport"fmt"constMAXint=3funcmain()a:=[]int1,3,5variintvarptr[MAX]*intfmt.Println(ptr)//这个打印出来的是[<nil><nil><nil>]fo 查看详情
golang入门到项目实战|golang构造函数(代码片段)
golang没有构造函数的概念,可以使用函数来模拟构造函数的功能。例如packagemainimport"fmt"typePersonstructnamestringageintfuncNewPerson(namestring,ageint)(*Person,error)ifname==""returnnil,fmt.Errorf("name不能为空")ifage<0returnnil... 查看详情
golang入门到项目实战|golang指针(代码片段)
Go语言中的函数传参都是值拷贝,当我们想要修改某个变量的时候,我们可以创建一个指向该变量地址的指针变量。传递数据使用指针,而无需拷贝数据。类型指针不能进行偏移和运算。Go语言中的指针操作非常简单... 查看详情
golang入门到项目实战|golang运算符(代码片段)
Go语言内置的运算符有:算术运算符关系运算符逻辑运算符位运算符赋值运算符算术运算符运算符描述+相加-相减*相乘/相除%求余注意:++(自增)和--(自减)在Go语言中是单独的语句,并不是... 查看详情
golang入门到项目实战golang方法
参考技术Ago语言没有面向对象的特性,也没有类对象的概念。但是,可以使用结构体来模拟这些特性,我们都知道面向对象里面有类方法等概念。我们也可以声明一些方法,属于某个结构体。Go中的方法,是一种特殊的函数,定... 查看详情
golang入门到项目实战|golang高阶函数(代码片段)
...yHello)运行结果[Running]gorun"d:\\SynologyDrive\\软件开发\\go\\golang入门到项目实战\\goproject\\360duote.com\\pro01\\tempCodeRunnerFile.go"Hello,tomgo语言函数作为返回值packagemainimport"fmt"funcadd(x,yint)intreturnx+yfuncsub(x,yint)intreturnx-yfunccal(sstr... 查看详情
golang入门到项目实战|golang中的if语句(代码片段)
go语言中的if语句和其他语言中的类似,都是根据给定的条件表达式运算结果来,判断执行流程。go语言if语句语法if布尔表达式/*在布尔表达式为true时执行*/注意:在go语言中布尔表达式不用使用括号。go语言if语句实例... 查看详情
golang入门到项目实战golangfor循环语句
参考技术Ago语言中的for循环,只有for关键字,去除了像其他语言中的while和dowhile.注意:for表达式不用加括号循环输出1到10运行结果初始条件,可以写到外面运行结果初始条件和结束条件都可以省略运行结果这种情况类似其他语... 查看详情
golang入门到项目实战|golang结构体指针(代码片段)
...p_name)运行结果[Running]gorun"d:\\SynologyDrive\\软件开发\\go\\golang入门到项目实战\\goproject\\360duote.com\\pro01\\test.go"name:tomp_name:0xc000050230*p_name:tomgo结构体指针实例packagemainimport"fmt"funcmain()typePersonstructidintnamestringvartom=P 查看详情
golang入门到项目实战golang并发变成之通道channel
...码块需要使用<-运算符:语法一个包含5个值的缓冲区的字符串类型的goroutine1通道。然后我们通过通道发送字符串“Australia”。这是从通道接收值的代码块:语法<-运算符附加到通道变量(goroutine1)的左侧,以接收来自通道... 查看详情
golang入门到项目实战|go语言遍历map(代码片段)
可以使用forrange循环进行map遍历,得到key和value值。遍历keypackagemainimport"fmt"funcmain()m:=make(map[string]string)m["name"]="tom"m["age"]="20"m["email 查看详情
golang入门到项目实战|golang模拟oop的属性和方法(代码片段)
golang没有面向对象的概念,也没有封装和概念,但是可以通过结构体struct和函数绑定来实现OOP的属性和方法等特性。接收者receiver方法。例如,想要定义一个Person类,有name和age属性,有eat/sleep/work方法。packagema... 查看详情
golang入门到项目实战golang中的if语句
参考技术Ago语言中的if语句和其他语言中的类似,都是根据给定的条件表达式运算结果来,判断执行流程。注意:在go语言中布尔表达式不用使用括号。根据布尔值flag判断程序运行结果初始变量可以声明在布尔表达式里面,注意... 查看详情