变量
goCopy code
package main
import (
	"fmt"
	"math"
)
func main() {
	// 声明并初始化变量
	var a = "initial"
	// 声明并初始化多个变量
	var b, c int = 1, 2
	// 声明并初始化变量,并推断其类型
	var d = true
	// 声明变量,但没有初始化,Go 会自动赋予零值
	var e float64
	// 使用短声明方式,声明并初始化变量(类型推断)
	f := float32(e)
	// 字符串拼接
	g := a + "foo"
	fmt.Println(a, b, c, d, e, f) // 输出: initial 1 2 true 0 0
	fmt.Println(g)                // 输出: initialfoo
	// 声明常量
	const s string = "constant"
	const h = 500000000
	const i = 3e20 / h
	// 输出常量和数学函数的计算结果
	fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
}代码解释:
- 
变量声明和初始化: - var a = "initial":声明一个名为- a的变量,初始值为字符串 "initial"。
- var b, c int = 1, 2:声明两个整数变量- b和- c,并分别初始化为 1 和 2。
- var d = true:声明一个布尔变量- d,初始值为- true。
- var e float64:声明一个浮点数变量- e,因为没有显式初始化,所以会被赋予浮点数类型的零值 0.0。
- f := float32(e):使用短声明方式,声明并初始化变量- f,类型为- float32,值从变量- e转换而来。
 
- 
字符串拼接: - g := a + "foo":使用- +运算符将字符串- a和 "foo" 进行拼接,结果存储在变量- g中。
 
- 
输出: - fmt.Println(...):使用- fmt.Println函数输出多个值,以空格分隔。
 
- 
常量声明和计算: - const s string = "constant":声明一个字符串常量- s,初始值为 "constant"。
- const h = 500000000:声明一个整数常量- h,初始值为 500000000。
- const i = 3e20 / h:声明一个浮点数常量- i,计算结果为- 3e20(科学计数法表示的值)除以常量- h。
 
- 
使用数学函数: - math.Sin(h)和- math.Sin(i):使用- math包中的- Sin函数分别计算- h和- i的正弦值。
 
for
goCopy code
package main
import "fmt"
func main() {
	// 无限循环,直到遇到 break
	i := 1
	for {
		fmt.Println("loop")
		break
	}
	// 基本的 for 循环,从 7 到 8
	for j := 7; j < 9; j++ {
		fmt.Println(j)
	}
	// 使用 continue 跳过偶数
	for n := 0; n < 5; n++ {
		if n%2 == 0 {
			continue
		}
		fmt.Println(n)
	}
	// 使用 for 循环实现类似 while 的效果
	for i <= 3 {
		fmt.Println(i)
		i = i + 1
	}
}代码解释:
- for {...}:这是一个无限循环,因为没有在循环条件中提供任何条件。在循环体内部,- fmt.Println("loop")输出字符串 "loop",然后通过- break语句跳出循环。这将导致循环仅迭代一次。
- for j := 7; j < 9; j++ {...}:这是一个基本的- for循环,它从- j等于 7 开始,每次迭代增加- j的值,直到- j小于 9。在循环体内,- fmt.Println(j)打印当前- j的值。
- for n := 0; n < 5; n++ {...}:这个- for循环在- n从 0 到 4 变化时迭代。在循环体内部,通过检查- n%2 == 0来判断- n是否为偶数,如果是偶数,那么- continue语句会跳过当前迭代,直接进行下一次迭代。这样,只有奇数会被打印出来。
- for i <= 3 {...}:这个- for循环模拟了类似于- while的行为。当- i小于等于 3 时,循环会一直迭代。在每次迭代中,- fmt.Println(i)打印当前的- i值,然后通过- i = i + 1增加- i的值。
if
goCopy code
package main
import "fmt"
func main() {
	// 检查奇偶性
	if 7%2 == 0 {
		fmt.Println("7 is even")
	} else {
		fmt.Println("7 is odd")
	}
	// 检查是否能被 4 整除
	if 8%4 == 0 {
		fmt.Println("8 is divisible by 4")
	}
	// 使用条件语句块进行条件判断和多分支
	if num := 9; num < 0 {
		fmt.Println(num, "is negative")
	} else if num < 10 {
		fmt.Println(num, "has 1 digit")
	} else {
		fmt.Println(num, "has multiple digits")
	}
}代码解释:
- 
if condition { ... } else { ... }:这是一个基本的if-else语句结构。如果condition为真(true),则执行位于{ ... }内的代码块,否则执行位于else { ... }内的代码块。
- 
if 7%2 == 0 { ... } else { ... }:这个条件判断语句检查 7 是否为偶数。由于 7 除以 2 的余数不为 0,所以执行else块,输出 "7 is odd"。
- 
if 8%4 == 0 { ... }:这个条件判断语句检查 8 是否能被 4 整除。由于 8 能被 4 整除,所以输出 "8 is divisible by 4"。
- 
if num := 9; num < 0 { ... } else if num < 10 { ... } else { ... }:这个条件语句块演示了 Go 语言中的局部变量初始化。在if语句的条件中,使用num := 9初始化了一个局部变量num。然后根据num的值进行多分支判断:- 如果 num小于 0,输出 "9 is negative"。
- 否则,如果 num小于 10,输出 "9 has 1 digit"。
- 如果上述条件都不满足,则输出 "9 has multiple digits"。
 
- 如果 
switch
goCopy code
package main
import (
	"fmt"
	"time"
)
func main() {
	// 基本的 switch 语句,匹配不同的 case
	a := 2
	switch a {
	case 1:
		fmt.Println("one")
	case 2:
		fmt.Println("two")
	case 3:
		fmt.Println("three")
	case 4, 5:
		fmt.Println("four or five")
	default:
		fmt.Println("other")
	}
	// 使用无条件表达式的 switch 语句,根据时间判断上午或下午
	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("It's before noon")
	default:
		fmt.Println("It's after noon")
	}
}代码解释:
- 
switch a { ... }:这是一个基本的switch语句结构。它根据变量a的值,匹配不同的case分支。在这个例子中,变量a的值为 2,所以输出 "two"。
- 
case 4, 5::这个case分支匹配值为 4 或 5 的情况,输出 "four or five"。这里可以同时匹配多个值。
- 
default::当没有任何case分支匹配时,将执行default分支,输出 "other"。
- 
使用无条件表达式的 switch语句:- t := time.Now():使用- time.Now()获取当前时间。
- switch { ... }:这个- switch语句没有在- switch关键字后面添加表达式。每个- case分支会根据条件判断是否匹配,条件在- case分支中的表达式中定义。
- t.Hour() < 12::这个条件判断检查当前时间的小时数是否小于 12。如果为真,执行第一个- case分支,输出 "It's before noon"。否则,执行- default分支,输出 "It's after noon"。
 
array
goCopy code
package main
import "fmt"
func main() {
	// 声明一个长度为 5 的整数数组
	var a [5]int
	// 在数组的第 5 个位置赋值为 100
	a[4] = 100
	// 输出数组的第 2 个位置的值
	fmt.Println("get:", a[2])
	// 输出数组的长度
	fmt.Println("len:", len(a))
	// 声明并初始化一个包含 5 个整数的数组
	b := [5]int{1, 2, 3, 4, 5}
	fmt.Println(b)
	// 声明一个 2x3 的整数数组
	var twoD [2][3]int
	// 使用循环为数组赋值
	for i := 0; i < 2; i++ {
		for j := 0; j < 3; j++ {
			twoD[i][j] = i + j
		}
	}
	fmt.Println("2d: ", twoD)
}代码解释:
- var a [5]int:这是一个长度为 5 的整数数组的声明。在 Go 中,数组的长度也是其类型的一部分。
- a[4] = 100:将数组- a的第 5 个元素(下标为 4)赋值为 100。
- fmt.Println("get:", a[2]):输出数组- a中的第 3 个元素(下标为 2)的值。
- fmt.Println("len:", len(a)):输出数组- a的长度,即 5。
- b := [5]int{1, 2, 3, 4, 5}:使用数组字面值初始化一个包含 1 到 5 的整数数组。
- var twoD [2][3]int:声明一个二维数组,其维度为 2x3。
- 嵌套循环 for i := 0; i < 2; i++和for j := 0; j < 3; j++:使用嵌套循环为二维数组twoD赋值,数组中的每个元素的值为其行数和列数之和。
slice
goCopy code
package main
import "fmt"
func main() {
	// 使用 make 创建一个长度为 3 的字符串切片
	s := make([]string, 3)
	// 设置切片的元素值
	s[0] = "a"
	s[1] = "b"
	s[2] = "c"
	// 输出切片的第 3 个元素
	fmt.Println("get:", s[2])   // 输出:c
	// 输出切片的长度
	fmt.Println("len:", len(s)) // 输出:3
	// 使用 append 向切片中追加元素
	s = append(s, "d")
	s = append(s, "e", "f")
	fmt.Println(s) // 输出:[a b c d e f]
	// 使用 copy 复制切片
	c := make([]string, len(s))
	copy(c, s)
	fmt.Println(c) // 输出:[a b c d e f]
	// 使用切片操作获取部分切片
	fmt.Println(s[2:5]) // 输出:[c d e]
	fmt.Println(s[:5])  // 输出:[a b c d e]
	fmt.Println(s[2:])  // 输出:[c d e f]
	// 直接初始化切片
	good := []string{"g", "o", "o", "d"}
	fmt.Println(good) // 输出:[g o o d]
}代码解释:
- 
s := make([]string, 3):使用make创建一个长度为 3 的字符串切片。
- 
切片元素设置: - s[0] = "a":设置切片- s的第一个元素为字符串 "a"。
- s[1] = "b":设置切片- s的第二个元素为字符串 "b"。
- s[2] = "c":设置切片- s的第三个元素为字符串 "c"。
 
- 
fmt.Println("get:", s[2]):输出切片s的第三个元素,即 "c"。
- 
fmt.Println("len:", len(s)):输出切片s的长度,即 3。
- 
使用 append向切片追加元素:- s = append(s, "d"):追加字符串 "d" 到切片- s。
- s = append(s, "e", "f"):同时追加字符串 "e" 和 "f" 到切片- s。
 
- 
使用 copy复制切片:- c := make([]string, len(s)):创建一个与切片- s长度相同的新切片- c。
- copy(c, s):将切片- s复制到切片- c。
 
- 
切片操作: - s[2:5]:从切片- s中获取索引从 2 到 4 的元素,即 "c", "d", "e"。
- s[:5]:从切片- s中获取索引从 0 到 4 的元素,即 "a", "b", "c", "d", "e"。
- s[2:]:从切片- s中获取索引从 2 开始到末尾的元素,即 "c", "d", "e", "f"。
 
- 
直接初始化切片: - good := []string{"g", "o", "o", "d"}:创建一个包含字符串的切片。
 
map
goCopy code
package main
import "fmt"
func main() {
	// 使用 make 创建一个字符串到整数的映射
	m := make(map[string]int)
	// 将键值对添加到映射
	m["one"] = 1
	m["two"] = 2
	// 输出映射的内容
	fmt.Println(m)           // 输出:map[one:1 two:2]
	// 输出映射的长度
	fmt.Println(len(m))      // 输出:2
	// 输出指定键的值
	fmt.Println(m["one"])    // 输出:1
	// 输出未定义键的值,默认为 0
	fmt.Println(m["unknown"]) // 输出:0
	// 使用两个返回值检查映射中是否存在指定键
	r, ok := m["unknown"]
	fmt.Println(r, ok) // 输出:0 false
	// 从映射中删除指定键的值
	delete(m, "one")
	// 直接初始化映射
	m2 := map[string]int{"one": 1, "two": 2}
	var m3 = map[string]int{"one": 1, "two": 2}
	fmt.Println(m2, m3)
}代码解释:
- 
m := make(map[string]int):使用make创建一个字符串到整数的映射。
- 
添加键值对到映射: - m["one"] = 1:将键 "one" 对应的值设为 1。
- m["two"] = 2:将键 "two" 对应的值设为 2。
 
- 
fmt.Println(m):输出映射的内容,结果为map[one:1 two:2]。
- 
fmt.Println(len(m)):输出映射的长度,结果为 2。
- 
fmt.Println(m["one"]):输出映射中键 "one" 对应的值,结果为 1。
- 
fmt.Println(m["unknown"]):输出映射中未定义键 "unknown" 对应的值,默认为 0。
- 
r, ok := m["unknown"]:使用两个返回值检查映射中是否存在键 "unknown"。r将会被赋值为该键的值(默认为 0),ok将会被赋值为false,表示未找到键 "unknown"。
- 
delete(m, "one"):从映射中删除键 "one" 及其对应的值。
- 
直接初始化映射: - m2 := map[string]int{"one": 1, "two": 2}:创建并初始化一个映射。
- var m3 = map[string]int{"one": 1, "two": 2}:通过- var关键字声明并初始化映射。
 
range
goCopy code
package main
import "fmt"
func main() {
	// 使用 range 迭代切片
	nums := []int{2, 3, 4}
	sum := 0
	for i, num := range nums {
		sum += num
		if num == 2 {
			fmt.Println("index:", i, "num:", num) // 输出:index: 0 num: 2
		}
	}
	fmt.Println(sum) // 输出:9
	// 使用 range 迭代映射
	m := map[string]string{"a": "A", "b": "B"}
	for k, v := range m {
		fmt.Println(k, v) // 输出:b B; a A
	}
	// 使用 range 迭代映射的键
	for k := range m {
		fmt.Println("key", k) // 输出:key a; key b
	}
}代码解释
- 
nums := []int{2, 3, 4}:声明一个整数切片nums,包含元素 2、3 和 4。
- 
使用 range迭代切片:- for i, num := range nums { ... }:使用- range关键字迭代切片- nums,- i是当前元素的索引,- num是当前元素的值。
- sum += num:将切片中的每个元素值累加到- sum变量中。
- if num == 2 { ... }:如果当前元素的值等于 2,输出索引和值。
 
- 
fmt.Println(sum):输出sum的值,即切片中所有元素的和,结果为 9。
- 
使用 range迭代映射:- for k, v := range m { ... }:使用- range关键字迭代映射- m,- k是当前键,- v是当前键对应的值。
- fmt.Println(k, v):输出映射中的键和值。
 
- 
使用 range迭代映射的键:- for k := range m { ... }:使用- range关键字迭代映射- m的键。
- fmt.Println("key", k):输出映射中的每个键。
 
func
goCopy code
package main
import "fmt"
// 定义一个接受两个整数参数并返回它们之和的函数
func add(a int, b int) int {
	return a + b
}
// 可简化参数类型定义的函数
func add2(a, b int) int {
	return a + b
}
// 定义一个函数用于检查映射中是否存在指定的键,并返回对应的值和是否存在的布尔值
func exists(m map[string]string, k string) (v string, ok bool) {
	v, ok = m[k]
	return v, ok
}
func main() {
	// 调用 add 函数,计算 1 + 2
	res := add(1, 2)
	fmt.Println(res) // 输出:3
	// 调用 exists 函数,检查映射中是否存在键 "a"
	v, ok := exists(map[string]string{"a": "A"}, "a")
	fmt.Println(v, ok) // 输出:A true
}代码解释:
goCopy code
package main
import "fmt"
// 定义一个接受两个整数参数并返回它们之和的函数
func add(a int, b int) int {
	return a + b
}
// 可简化参数类型定义的函数
func add2(a, b int) int {
	return a + b
}
// 定义一个函数用于检查映射中是否存在指定的键,并返回对应的值和是否存在的布尔值
func exists(m map[string]string, k string) (v string, ok bool) {
	v, ok = m[k]
	return v, ok
}
func main() {
	// 调用 add 函数,计算 1 + 2
	res := add(1, 2)
	fmt.Println(res) // 输出:3
	// 调用 exists 函数,检查映射中是否存在键 "a"
	v, ok := exists(map[string]string{"a": "A"}, "a")
	fmt.Println(v, ok) // 输出:A true
}- func add(a int, b int) int { ... }:这是一个定义函数- add的语句。该函数接受两个整数参数- a和- b,并返回它们的和。
- func add2(a, b int) int { ... }:这是一个更简化的函数定义方式。参数类型可以在最后一个参数前进行简化。
- func exists(m map[string]string, k string) (v string, ok bool) { ... }:这是定义函数- exists的语句。该函数接受一个映射- m和一个键- k,并返回键- k对应的值- v和一个布尔值- ok,表示键是否存在。
- 在 main函数中,通过调用add函数,将 1 和 2 相加并输出结果。
- 在 main函数中,通过调用exists函数,检查映射map[string]string{"a": "A"}是否存在键 "a",并输出键对应的值和布尔值。
pointer
goCopy code
package main
import "fmt"
// 传递一个整数值,但在函数内部对参数值进行修改不影响原始值
func add2(n int) {
	n += 2
}
// 传递一个整数的指针,可以通过指针间接修改原始值
func add2ptr(n *int) {
	*n += 2
}
func main() {
	n := 5
	add2(n)
	fmt.Println(n) // 输出:5,因为 add2 函数内部对参数值进行修改,不影响原始值
	add2ptr(&n)
	fmt.Println(n) // 输出:7,因为 add2ptr 函数接受指针参数,通过指针修改了原始值
}代码解释:
- func add2(n int) { ... }:这是一个函数,接受一个整数值作为参数- n。在函数内部,对- n的修改不会影响传入的原始值,因为传递的是值的副本。
- func add2ptr(n *int) { ... }:这是另一个函数,接受一个整数的指针作为参数- n。在函数内部,通过解引用指针- *n并对其进行修改,可以影响传入的原始值。
- 在 main函数中,声明变量n并赋值为 5。
- add2(n):调用- add2函数,并传递- n的值。这里传递的是值的副本,所以函数内部对参数- n的修改不会影响原始值。
- fmt.Println(n):输出- n的值,结果为 5,因为- add2函数内部的修改不影响原始值。
- add2ptr(&n):调用- add2ptr函数,并传递- n的地址(指针)。这里传递的是指针,所以函数内部对指针解引用并进行修改会影响原始值。
- fmt.Println(n):输出- n的值,结果为 7,因为- add2ptr函数通过指针修改了原始值。
struct
goCopy code
package main
import "fmt"
// 定义一个名为 user 的结构体类型,包含 name 和 password 字段
type user struct {
	name     string
	password string
}
func main() {
	// 使用不同方式初始化 user 结构体变量
	a := user{name: "wang", password: "1024"}
	b := user{"wang", "1024"}
	c := user{name: "wang"}
	c.password = "1024"
	var d user
	d.name = "wang"
	d.password = "1024"
	// 输出结构体变量的值
	fmt.Println(a, b, c, d) // 输出:{wang 1024} {wang 1024} {wang 1024} {wang 1024}
	// 调用 checkPassword 函数,检查密码是否匹配
	fmt.Println(checkPassword(a, "haha")) // 输出:false
	// 调用 checkPassword2 函数,通过指针传递结构体
	fmt.Println(checkPassword2(&a, "haha")) // 输出:false
}
// 定义函数 checkPassword,接受结构体和密码作为参数,返回密码是否匹配
func checkPassword(u user, password string) bool {
	return u.password == password
}
// 定义函数 checkPassword2,接受结构体指针和密码作为参数,返回密码是否匹配
func checkPassword2(u *user, password string) bool {
	return u.password == password
}代码解释:
- 
type user struct { ... }:这是定义结构体类型user的语句。结构体类型包含两个字段:name和password。
- 
使用不同的方式初始化 user结构体变量:- a := user{name: "wang", password: "1024"}:通过字段名初始化结构体变量- a。
- b := user{"wang", "1024"}:使用字段值的列表初始化结构体变量- b。
- c := user{name: "wang"}:通过字段名初始化结构体变量- c的部分字段,然后单独设置其- password字段。
- var d user:声明一个变量- d为零值的结构体,然后分别设置其字段的值。
 
- 
fmt.Println(a, b, c, d):输出四个结构体变量的值。
- 
checkPassword函数:接受一个user结构体值和一个密码字符串,检查密码是否匹配,并返回布尔值。
- 
checkPassword2函数:接受一个user结构体指针和一个密码字符串,检查密码是否匹配,并返回布尔值。
- 
在 main函数中,调用checkPassword函数,传递一个结构体值和密码,检查密码是否匹配,结果为false。
- 
在 main函数中,调用checkPassword2函数,传递一个结构体指针和密码,检查密码是否匹配,结果为false。
struct-method
goCopy code
package main
import "fmt"
type user struct {
	name     string
	password string
}
// 为 user 结构体定义一个方法 checkPassword,接收者为值类型 user
func (u user) checkPassword(password string) bool {
	return u.password == password
}
// 为 user 结构体定义一个方法 resetPassword,接收者为指针类型 *user
func (u *user) resetPassword(password string) {
	u.password = password
}
func main() {
	// 创建一个 user 结构体变量 a
	a := user{name: "wang", password: "1024"}
	// 调用 resetPassword 方法,重置密码
	a.resetPassword("2048")
	// 调用 checkPassword 方法,检查密码是否匹配
	fmt.Println(a.checkPassword("2048")) // 输出:true
}代码解释:
- type user struct { ... }:这是定义结构体类型- user的语句。
- func (u user) checkPassword(password string) bool { ... }:这是为结构体- user定义一个方法- checkPassword的语句。方法接收者为结构体值类型- user。该方法接受一个密码字符串作为参数,检查密码是否匹配,并返回布尔值。
- func (u *user) resetPassword(password string) { ... }:这是为结构体- user定义另一个方法- resetPassword的语句。方法接收者为结构体指针类型- *user。该方法接受一个密码字符串作为参数,重置结构体中的密码字段。
- 在 main函数中,创建一个user结构体变量a,设置初始用户名和密码。
- a.resetPassword("2048"):调用- resetPassword方法,通过指针接收者修改了结构体变量- a的密码。
- fmt.Println(a.checkPassword("2048")):调用- checkPassword方法,检查密码是否匹配 "2048",输出结果为- true。
error
goCopy code
package main
import (
	"errors"
	"fmt"
)
type user struct {
	name     string
	password string
}
// 定义一个函数,查找指定名称的用户
func findUser(users []user, name string) (v *user, err error) {
	for _, u := range users {
		if u.name == name {
			return &u, nil // 返回找到的用户和没有错误
		}
	}
	return nil, errors.New("not found") // 没有找到用户,返回错误
}
func main() {
	// 在给定用户切片中查找 "wang"
	u, err := findUser([]user{{"wang", "1024"}}, "wang")
	if err != nil {
		fmt.Println(err) // 没有错误,输出为空
		return
	}
	fmt.Println(u.name) // 输出:wang
	// 在给定用户切片中查找 "li"
	if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
		fmt.Println(err) // 输出:not found
		return
	} else {
		fmt.Println(u.name) // 不会执行到这里
	}
}代码解释:
- errors.New("not found"):使用- errors包中的- New函数创建一个新的错误实例,内容为 "not found"。
- findUser函数:接受用户切片和名称作为参数,遍历用户切片,如果找到与名称匹配的用户,则返回用户指针和没有错误;如果没有找到,则返回- not found错误。
- 在 main函数中,调用findUser函数,传递用户切片和名称 "wang"。如果找到用户,将用户指针存储在u中,如果未找到,将返回一个错误实例,存储在err中。
- 使用 if err != nil判断错误是否存在。如果存在错误,则输出错误内容。
- 在另一个 if分支中,再次调用findUser函数,查找名称 "li"。如果找到用户,将用户指针存储在u中,如果未找到,将返回一个错误实例,存储在err中。如果存在错误,输出错误内容为 "not found"。
string
goCopy code
package main
import (
	"fmt"
	"strings"
)
func main() {
	a := "hello"
	// 判断字符串是否包含子串
	fmt.Println(strings.Contains(a, "ll")) // 输出:true
	// 计算子串在字符串中出现的次数
	fmt.Println(strings.Count(a, "l")) // 输出:2
	// 判断字符串是否以指定前缀开头
	fmt.Println(strings.HasPrefix(a, "he")) // 输出:true
	// 判断字符串是否以指定后缀结尾
	fmt.Println(strings.HasSuffix(a, "llo")) // 输出:true
	// 返回子串在字符串中首次出现的索引
	fmt.Println(strings.Index(a, "ll")) // 输出:2
	// 将字符串切片用指定分隔符连接
	fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // 输出:he-llo
	// 重复字符串指定次数
	fmt.Println(strings.Repeat(a, 2)) // 输出:hellohello
	// 替换字符串中的指定子串
	fmt.Println(strings.Replace(a, "e", "E", -1)) // 输出:hEllo
	// 使用指定分隔符分割字符串为切片
	fmt.Println(strings.Split("a-b-c", "-")) // 输出:[a b c]
	// 将字符串转换为小写
	fmt.Println(strings.ToLower(a)) // 输出:hello
	// 将字符串转换为大写
	fmt.Println(strings.ToUpper(a)) // 输出:HELLO
	// 返回字符串的长度(字节数)
	fmt.Println(len(a)) // 输出:5
	b := "你好"
	// 返回字符串的长度(字节数)
	fmt.Println(len(b)) // 输出:6
}代码解释:
这个代码片段展示了 Go 语言中 strings 包中一些常用的字符串操作函数的用法,包括判断是否包含、计数、前缀和后缀判断、索引查找、连接、重复、替换、分割、大小写转换以及获取字符串长度。注意,在计算字符串长度时,使用的是字节数,而不是字符数。
fmt
goCopy code
package main
import "fmt"
type point struct {
	x, y int
}
func main() {
	s := "hello"
	n := 123
	p := point{1, 2}
	// 使用 fmt.Println 输出多个值
	fmt.Println(s, n) // 输出:hello 123
	fmt.Println(p)    // 输出:{1 2}
	// 使用 fmt.Printf 进行格式化输出
	fmt.Printf("s=%v\n", s)  // 输出:s=hello
	fmt.Printf("n=%v\n", n)  // 输出:n=123
	fmt.Printf("p=%v\n", p)  // 输出:p={1 2}
	fmt.Printf("p=%+v\n", p) // 输出:p={x:1 y:2}
	fmt.Printf("p=%#v\n", p) // 输出:p=main.point{x:1, y:2}
	f := 3.141592653
	fmt.Println(f)          // 输出:3.141592653
	fmt.Printf("%.2f\n", f) // 输出:3.14
}代码解释:
- 
type point struct { ... }:定义了名为point的结构体类型,包含两个整数字段x和y。
- 
使用 fmt.Println(s, n):使用fmt.Println函数同时输出多个值,结果为hello 123。
- 
使用 fmt.Printf进行格式化输出:- fmt.Printf("s=%v\n", s):使用- %v占位符将变量的值插入字符串中,结果为- s=hello。
- fmt.Printf("n=%v\n", n):同样,使用- %v插入变量的值,结果为- n=123。
- fmt.Printf("p=%v\n", p):使用- %v插入结构体变量- p的值,结果为- p={1 2}。
- fmt.Printf("p=%+v\n", p):使用- %+v插入结构体变量- p的值,带有字段名,结果为- p={x:1 y:2}。
- fmt.Printf("p=%#v\n", p):使用- %#v插入结构体变量- p的值,带有完整的类型和字段名,结果为- p=main.point{x:1, y:2}。
 
- 
使用 fmt.Println(f):输出浮点数f的值,结果为3.141592653。
- 
使用 fmt.Printf("%.2f\n", f):使用%.2f格式控制符将浮点数f格式化为小数点后保留两位的形式,结果为3.14。
json
goCopy code
package main
import (
	"encoding/json"
	"fmt"
)
type userInfo struct {
	Name  string
	Age   int      `json:"age"`    // 自定义 JSON 标签
	Hobby []string `json:"hobbies"` // 自定义 JSON 标签
}
func main() {
	a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
	// 将结构体编码为 JSON 格式的字节切片
	buf, err := json.Marshal(a)
	if err != nil {
		panic(err)
	}
	fmt.Println(buf)         // 输出:[123 34 78 97...]
	fmt.Println(string(buf)) // 输出:{"Name":"wang","age":18,"hobbies":["Golang","TypeScript"]}
	// 使用 json.MarshalIndent 进行格式化输出
	buf, err = json.MarshalIndent(a, "", "\t")
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf))
	// 将 JSON 格式的字节切片解码为结构体
	var b userInfo
	err = json.Unmarshal(buf, &b)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v\n", b) // 输出:main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
}代码解释:
- type userInfo struct { ... }:定义了- userInfo结构体类型,包含- Name、- Age和- Hobby字段。使用- json标签来自定义字段在 JSON 中的名称。
- json.Marshal(a):使用- json.Marshal函数将- a结构体编码为 JSON 格式的字节切片。
- json.MarshalIndent(a, "", "\t"):使用- json.MarshalIndent函数对- a结构体进行格式化编码,第二个参数是前缀,第三个参数是缩进字符串。
- json.Unmarshal(buf, &b):使用- json.Unmarshal函数将 JSON 格式的字节切片解码为结构体变量- b。
time
goCopy code
package main
import (
	"fmt"
	"time"
)
func main() {
	// 获取当前时间
	now := time.Now()
	fmt.Println(now) // 输出当前时间,类似:2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933
	// 构造指定时间
	t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
	t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
	fmt.Println(t) // 输出:2022-03-27 01:25:36 +0000 UTC
	// 获取时间的年、月、日、小时、分钟
	fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 输出:2022 March 27 1 25
	// 格式化时间为字符串
	fmt.Println(t.Format("2006-01-02 15:04:05")) // 输出:2022-03-27 01:25:36
	// 计算时间差
	diff := t2.Sub(t)
	fmt.Println(diff)                           // 输出:1h5m0s
	fmt.Println(diff.Minutes(), diff.Seconds()) // 输出:65 3900
	// 解析字符串为时间对象
	t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
	if err != nil {
		panic(err)
	}
	fmt.Println(t3 == t) // 输出:true
	// 获取当前时间的 Unix 时间戳
	fmt.Println(now.Unix()) // 输出当前时间的 Unix 时间戳,类似:1648738080
}代码解释:
- time.Now():获取当前时间。
- time.Date(year, month, day, hour, minute, second, nanosecond, location):构造指定时间。
- t.Year(),- t.Month(),- t.Day(),- t.Hour(),- t.Minute():获取时间的年、月、日、小时、分钟。
- t.Format(layout):将时间格式化为指定的字符串。
- t2.Sub(t):计算时间差。
- time.Parse(layout, value):将字符串解析为时间对象。
- now.Unix():获取当前时间的 Unix 时间戳。
strconv
goCopy code
package main
import (
	"fmt"
	"strconv"
)
func main() {
	// 将字符串转换为浮点数
	f, _ := strconv.ParseFloat("1.234", 64)
	fmt.Println(f) // 输出:1.234
	// 将字符串转换为整数
	n, _ := strconv.ParseInt("111", 10, 64)
	fmt.Println(n) // 输出:111
	// 支持十六进制转换
	n, _ = strconv.ParseInt("0x1000", 0, 64)
	fmt.Println(n) // 输出:4096
	// 将字符串转换为整数,简便函数 Atoi
	n2, _ := strconv.Atoi("123")
	fmt.Println(n2) // 输出:123
	// Atoi 在无法解析时会返回 0 和错误信息
	n2, err := strconv.Atoi("AAA")
	fmt.Println(n2, err) // 输出:0 strconv.Atoi: parsing "AAA": invalid syntax
}代码解释:
- strconv.ParseFloat(input, bitSize):将字符串转换为浮点数,- bitSize表示浮点数的位数。
- strconv.ParseInt(input, base, bitSize):将字符串转换为整数,- base表示输入的字符串是何种进制(0 表示自动识别进制),- bitSize表示整数的位数。
- strconv.Atoi(input):将字符串转换为整数,这是- strconv.ParseInt的简便函数,自动识别进制。
- 在 strconv.Atoi中,无法解析时会返回 0 和错误信息。
env
goCopy code
package main
import (
	"fmt"
	"os"
	"os/exec"
)
func main() {
	// 输出命令行参数
	fmt.Println(os.Args) // 输出:[/var/folders/8p/n34xxfnx38dg8bv_x8l62t_m0000gn/T/go-build3406981276/b001/exe/main a b c d]
	// 获取环境变量
	fmt.Println(os.Getenv("PATH")) // 输出环境变量 PATH 的值
	// 设置环境变量
	fmt.Println(os.Setenv("AA", "BB")) // 设置环境变量 AA 的值为 BB
	// 执行外部命令并获取输出
	buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf)) // 输出 grep 命令在 /etc/hosts 中查找的结果
}代码解释:
- os.Args:获取命令行参数,包括程序名和参数列表。
- os.Getenv(name):获取环境变量的值。
- os.Setenv(name, value):设置环境变量的值。
- exec.Command(command, args...):创建一个命令对象,- command表示命令名称,- args...表示命令参数。
- cmd.CombinedOutput():执行命令并获取标准输出和标准错误输出,如果命令执行失败,则返回错误。