经过之前的简单概念学习我们可以知道Go语言中的字符串以原生数据类型出现,使用字符串就和使用其他原生数据类型大同小异(如int
、bool
、float32
)。
而我们需要注意的是 Go 语言里的字符串的内部实现使用UTF-8
编码。
字符串的值为双引号(")
中的内容,可以在Go语言的源码中直接添加非ASCII码字符。
s1 := "hello"
s2 := "你好"
Go 语言的字符串常见转义符包含回车、换行、单双引号、制表符等。
转义符 含义 \r
回车符(返回行首) \n
换行符(直接跳到下一行的同列位置) \t
制表符 \'
单引号 \"
双引号 \\
反斜杠
Go语言中要定义一个多行字符串时,就必须使用反引号字符:
s1 := `how //第一行
are //第二行
you //第三行
`
fmt.Println(s1)
方法 介绍 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(){
s4 :="how are you"
//字符串分割
fmt.Println(strings.Split(s4, " "))
//判断是否包含
fmt.Println(strings.Contains(s4, "do"))
//判断前缀,后缀
fmt.Println(strings.HasPrefix(s4,"how"))
fmt.Println(strings.HasSuffix(s4."how"))
//判断子串位置
fmt.Println(strings.Index(s4, "o"))
//判断子串最后出现位置
fmt.Println(strings.LastIndex(s4,"o"))
}
Go 语言的字符有以下两种:
uint8
类型,或者叫 byte 型,代表一个ASCII码
字符。rune
类型,代表一个UTF-8字符
。当需要处理中文、日文或者其他复合字符时,则需要用到
rune
类型。rune
类型实际是一个int32
。Go 使用了特殊的 rune 类型来处理 Unicode,让基于 Unicode 的文本处理更为方便,也可以使用 byte 型进行默认字符串处理,性能和扩展性都有照顾。
要修改字符串,需要先将其转换成
[]rune
或[]byte
,完成后再转换为string
。无论哪种转换,都会重新分配内存,并复制字节数组。
func changeString() {
s1 := "big"
// 强制类型转换
byteS1 := []byte(s1)
byteS1[0] = 'p'
fmt.Println(string(byteS1))
s2 := "白萝卜"
runeS2 := []rune(s2)
runeS2[0] = '红'
fmt.Println(string(runeS2))
}
Go语言中只有强制类型转换,没有隐式类型转换。该语法只能在两个类型之间支持相互转换的时候使用。
T(表达式)//其中,T表示要转换的类型
举个例子,计算直角三角形的斜边长时使用math包的Sqrt()函数,该函数接收的是float64类型的参数,而变量a和b都是int类型的,这个时候就需要将a和b强制类型转换为float64类型。
func sqrt() {
var a, b = 3, 4
var c int
// math.Sqrt()接收的参数是float64类型,需要强制转换
c = int(math.Sqrt(float64(a*a + b*b)))
fmt.Println(c)
}
Go语言中最常用的流程控制有
if
和for
,还有扩展类的switch
和goto
if 表达式1 {
分支1
} else if 表达式2 {
分支2
} else{
分支3
}
强调一下,Go语言规定与if
匹配的左括号{
必须与if和表达式
放在同一行,{
放在其他位置会触发编译错误。 同理,与else
匹配的{
也必须与else
写在同一行,else
也必须与上一个if
或else if
右边的大括号在同一行。
if条件判断还可以在 if 表达式之前添加一个执行语句,再根据变量值进行判断。
func ans() {
if ans := 60; ans >= 90 {
fmt.Println("A")
} else if score > 75 {
fmt.Println("B")
} else {
fmt.Println("C")
}
}
我们可以思考一下这两种写法的区别在哪里
特性 基本写法 特殊写法 变量声明 必须在if外部声明 可在if条件前声明 变量作用域 整个函数作用域 仅限于if-else块内 代码简洁性 相对冗长 更简洁紧凑 可读性 传统写法更易理解 需要适应Go特有语法
特殊写法的优势在于:
- 限制变量作用域:声明的变量只在if-else块内有效
- 减少命名冲突:避免在外部作用域声明临时变量
- 代码更紧凑:将变量声明与条件判断合并
Go 语言中的所有循环类型均可以使用for
关键字来完成。
for 初始语句;条件表达式;结束语句{
循环体语句
}
for循环的初始语句可以被忽略,但是初始语句后的分号必须要写
func forDemo() {
i := 0
for ; i < 10; i++ {
fmt.Println(i)
}
}
for循环的初始语句和结束语句都可以省略
func forDemo3() {
i := 0
for i < 10 {
fmt.Println(i)
i++
}
}
for循环可以通过break
、goto
、return
、panic
语句强制退出循环。
Go语言中可以使用
for range
遍历数组、切片、字符串、map 及通道(channel)。 通过for range
遍历的返回值有以下规律:
- 数组、切片、字符串返回索引和值。
- map返回键和值。
- 通道(channel)只返回通道内的值。
举个冒泡排序的简单例子,如果我们要把结果输出:
package main
import "fmt"
func main() {
var num = [5]int{2, 4, 3, 5, 1}
for i := 0; i < len(num)-1; i++ {
for j := 0; j < len(num)-1-i; j++ {
if num[j] > num[j+1] {
t := num[j]
num[j] = num[j+1]
num[j+1] = t
}
}
}
for _, nums := range num {
fmt.Printf("%d ", nums)
}
}
输出:1 2 3 4 5
使用
switch
语句可方便地对大量的值进行条件判断。
func switchDemo1() {
finger := 3
switch finger {
case 1:
fmt.Println("大拇指")
case 2:
fmt.Println("食指")
case 3:
fmt.Println("中指")
case 4:
fmt.Println("无名指")
case 5:
fmt.Println("小拇指")
default:
fmt.Println("无效的输入!")
}
}
Go语言规定每个switch
只能有一个default
分支。
func test() {
switch n := 7; n {
case 1, 3, 5, 7, 9:
fmt.Println("奇数")
case 2, 4, 6, 8:
fmt.Println("偶数")
default:
fmt.Println(n)
}
}
func scoretest() {
score := 90
switch {
case score < 60:
fmt.Println("不及格")
case score >=60 && score <= 80:
fmt.Println("良好")
case score >=80 && score <=100:
fmt.Println("优秀")
default:
fmt.Println("无法判断")
}
}
goto
语句通过标签进行代码间的无条件跳转。goto
语句可以在快速跳出循环、避免重复退出上有一定的帮助。Go语言中使用goto
语句能简化一些代码的实现过程。
func gotoDemo() {
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
// 设置退出标签
goto breakTag
}
fmt.Printf("%v-%v\n", i, j)
}
}
return
// 标签
breakTag:
fmt.Println("结束for循环")
}
break
语句可以结束for
、switch
和select
的代码块。
break
语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的for
、switch
和select
的代码块上。
func breakDemo() {
BREAKDEMO:
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
break BREAKDEMO
}
fmt.Printf("%v-%v\n", i, j)
}
}
fmt.Println("...")
}
continue
语句可以结束当前循环,开始下一次的循环迭代过程,仅限在for
循环内使用。在
continue
语句后添加标签时,表示开始标签对应的循环。用法和break类似
func continueDemo() {
forloop1:
for i := 0; i < 5; i++ {
// forloop2:
for j := 0; j < 5; j++ {
if i == 2 && j == 2 {
continue forloop1
}
fmt.Printf("%v-%v\n", i, j)
}
}
}