变量
goCopy code
package mainimport ("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 0fmt.Println(g) // 输出: initialfoo// 声明常量const s string = "constant"const h = 500000000const 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 mainimport "fmt"func main() {// 无限循环,直到遇到 breaki := 1for {fmt.Println("loop")break}// 基本的 for 循环,从 7 到 8for 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 mainimport "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 mainimport ("fmt""time"
)func main() {// 基本的 switch 语句,匹配不同的 casea := 2switch 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 mainimport "fmt"func main() {// 声明一个长度为 5 的整数数组var a [5]int// 在数组的第 5 个位置赋值为 100a[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 mainimport "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 mainimport "fmt"func main() {// 使用 make 创建一个字符串到整数的映射m := make(map[string]int)// 将键值对添加到映射m["one"] = 1m["two"] = 2// 输出映射的内容fmt.Println(m) // 输出:map[one:1 two:2]// 输出映射的长度fmt.Println(len(m)) // 输出:2// 输出指定键的值fmt.Println(m["one"]) // 输出:1// 输出未定义键的值,默认为 0fmt.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 mainimport "fmt"func main() {// 使用 range 迭代切片nums := []int{2, 3, 4}sum := 0for i, num := range nums {sum += numif 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 mainimport "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 + 2res := 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 mainimport "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 + 2res := 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 mainimport "fmt"// 传递一个整数值,但在函数内部对参数值进行修改不影响原始值
func add2(n int) {n += 2
}// 传递一个整数的指针,可以通过指针间接修改原始值
func add2ptr(n *int) {*n += 2
}func main() {n := 5add2(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 mainimport "fmt"// 定义一个名为 user 的结构体类型,包含 name 和 password 字段
type user struct {name stringpassword string
}func main() {// 使用不同方式初始化 user 结构体变量a := user{name: "wang", password: "1024"}b := user{"wang", "1024"}c := user{name: "wang"}c.password = "1024"var d userd.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 mainimport "fmt"type user struct {name stringpassword 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 结构体变量 aa := 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 mainimport ("errors""fmt"
)type user struct {name stringpassword 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 foundreturn} 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 mainimport ("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)) // 输出:5b := "你好"// 返回字符串的长度(字节数)fmt.Println(len(b)) // 输出:6
}
代码解释:
这个代码片段展示了 Go 语言中 strings 包中一些常用的字符串操作函数的用法,包括判断是否包含、计数、前缀和后缀判断、索引查找、连接、重复、替换、分割、大小写转换以及获取字符串长度。注意,在计算字符串长度时,使用的是字节数,而不是字符数。
fmt
goCopy code
package mainimport "fmt"type point struct {x, y int
}func main() {s := "hello"n := 123p := point{1, 2}// 使用 fmt.Println 输出多个值fmt.Println(s, n) // 输出:hello 123fmt.Println(p) // 输出:{1 2}// 使用 fmt.Printf 进行格式化输出fmt.Printf("s=%v\n", s) // 输出:s=hellofmt.Printf("n=%v\n", n) // 输出:n=123fmt.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.141592653fmt.Println(f) // 输出:3.141592653fmt.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 mainimport ("encoding/json""fmt"
)type userInfo struct {Name stringAge 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 userInfoerr = 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 mainimport ("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) // 输出:1h5m0sfmt.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 mainimport ("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// 将字符串转换为整数,简便函数 Atoin2, _ := 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 mainimport ("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():执行命令并获取标准输出和标准错误输出,如果命令执行失败,则返回错误。