Golang下载地址:https://golang.google.cn/dl/





# GOPATH
D:\GolandProjects

# Path
%GOROOT%\bin

# 启用Go模块支持
go env -w GO111MODULE=on
# 配置Go模块下载代理
go env -w GOPROXY=https://goproxy.cn,direct


package main
import "fmt"
func main() {
// var 变量名字 类型 = 表达式
// 单个变量定义
//var name string = "xumeng03!"
//var name = "xumeng03!"
//name := "xumeng03!"
var name string
name = "xumeng03"
fmt.Println("hello", name)
// 多个变量定义
//var name1, name2 = "xumeng", "xumeng03"
var (
name1 = "xumeng03"
name2 = "xumeng"
)
fmt.Println("hello", name1, name2)
}
package main
import "fmt"
func main() {
// const 变量名字 类型 = 表达式
const name string="xumeng03"
// 报错
//name = "xumeng"
//const name1 string
//name1 = "aaa"
fmt.Println("hello", name)
}
| 数据类型 | 类型解释 | 默认零值 | 示例 | 传递 |
|---|---|---|---|---|
| bool | 布尔型,值为true或false | false | var vbool bool = true | 值 |
| uint8 | 8位无符号整型,取值范围为0到255 | 0 | var vuint8 uint8 = 1 | 值 |
| uint16 | 16位无符号整型,取值范围为0到65535 | 0 | var vuint16 uint16 = 1 | 值 |
| uint32 | 32位无符号整型,取值范围为0到4294967295 | 0 | var vuint32 uint32 = 1 | 值 |
| uint64 | 64位无符号整型,取值范围为0到4294967295 | 0 | var vuint64 uint64 = 1 | 值 |
| uint | 32位/64位无符号整型,具体位数与操作系统有关 | var vuint uint = 1 | 值 | |
| int8 | 8位有符号整型,取值范围为-128到127 | 0 | var vint8 int8 = 2 | 值 |
| int16 | 16位有符号整型,取值范围为-32768到32767 | 0 | var vint16 int16 = 2 | 值 |
| int32 | 32位有符号整型,取值范围为-2147483648到2147483647 | 0 | var vint32 int32 = 2 | 值 |
| int64 | 64位有符号整型,取值范围为-9223372036854775808到9223372036854775807 | 0 | var vint64 int64 = 2 | 值 |
| int | 32位/64位有符号整型,具体位数与操作系统有关 | var vint int = 2 | 值 | |
| float32 | 32位浮点型,可以表示小数,精度为7位小数 | 0 | var vfloat32 float32 = 3.14 | 值 |
| float64 | 64位浮点型,可以表示小数,精度为15位小数 | 0 | var vfloat64 float64 = 3.14 | 值 |
| string | 字符串类型,由一串Unicode码点组成 | “” | var vstring string = “hello world!” | 值 |
package main
import (
"fmt"
"math"
"strconv"
)
func main() {
// bool
var vbool bool
fmt.Printf("类型: %T,默认值: %t\n", vbool, vbool)
// uint8、uint16、uint32、uint64(uint)
var vuint uint
var vuint8 uint8
var vuint16 uint16
var vuint32 uint32
var vuint64 uint64
fmt.Printf("类型: %T,默认值: %d,最小值: %d,最大值: %d\n", vuint, vuint, 0, strconv.FormatUint(math.MaxUint, 10))
fmt.Printf("类型: %T,默认值: %d,最小值: %d,最大值: %d\n", vuint8, vuint8, 0, math.MaxUint8)
fmt.Printf("类型: %T,默认值: %d,最小值: %d,最大值: %d\n", vuint16, vuint16, 0, math.MaxUint16)
fmt.Printf("类型: %T,默认值: %d,最小值: %d,最大值: %d\n", vuint32, vuint32, 0, math.MaxUint32)
fmt.Printf("类型: %T,默认值: %d,最小值: %d,最大值: %d\n", vuint64, vuint64, 0, strconv.FormatUint(math.MaxUint64, 10))
// int8、int16、int32、int64
var vint int
var vint8 int8
var vint16 int16
var vint32 int32
var vint64 int64
fmt.Printf("类型: %T,默认值: %d,最小值: %d,最大值: %d\n", vint, vint, math.MinInt, math.MaxInt)
fmt.Printf("类型: %T,默认值: %d,最小值: %d,最大值: %d\n", vint8, vint8, math.MinInt8, math.MaxInt8)
fmt.Printf("类型: %T,默认值: %d,最小值: %d,最大值: %d\n", vint16, vint16, math.MinInt16, math.MaxInt16)
fmt.Printf("类型: %T,默认值: %d,最小值: %d,最大值: %d\n", vint32, vint32, math.MinInt32, math.MaxInt32)
fmt.Printf("类型: %T,默认值: %d,最小值: %d,最大值: %d\n", vint64, vint64, math.MinInt64, math.MaxInt64)
// float32、float64
var vfloat32 float32
var vfloat64 float64
fmt.Printf("类型: %T,默认值: %f\n", vfloat32, vfloat32)
fmt.Printf("类型: %T,默认值: %f\n", vfloat64, vfloat64)
// string(值传递)
var vstring string
fmt.Printf("类型: %T,默认值: %s\n", vstring, vstring)
}
只有类型兼容的才可以转换!
package main
import (
"fmt"
)
func main() {
var vint8 int8
var vint16 int16
//vint16 = vint8;
vint16 = int16(vint8);
fmt.Printf("类型: %T,值: %d", vint16, vint16)
// 大转小会有精度丢失问题
//var vint8 int8
//var vint16 int16 = 257
//vint8 = int8(vint16)
//fmt.Printf("类型: %T,值: %d", vint8, vint8)
}
| 数据类型 | 类型解释 | 默认值 | 示例 | 传递 |
|---|---|---|---|---|
| Array | 相同类型且长度固定的数据集合 | [0,0,0] | var arr1 = [3]int{1, 2, 3} | 值 |
| Slice | 相同类型且长度不固定的数据集合(底层是数组,也被称为动态数组) | [] | var sli1= []int{1, 2, 3} | 引用 |
| Map | 键值对 | [] | var m = map[string]string{“ke y”: “value”} | 引用 |
| Func | 函数类型 | - | - | 引用 |
| Pointer | 指针类型 | - | - | 值/引用 |
| Struct | 结构体类型 | - | - | 值 |
| Interface | 接口类型 | - | - | - |
package main
import (
"fmt"
)
func main() {
// 一维数组
// 方法1:声明并初始化一个固定长度的数组
// 方法2:使用数组字面量初始化数组
var arr2 = [3]int{1, 2, 3}
// 方法3:省略数组长度的方式初始化数组
var arr3 = [...]int{1, 2, 3, 4, 5, 6, 7}
// 方法4:省略数组长度的方式并使用索引初始化数组
var arr4 = [...]int{2: 3, 4: 5}
fmt.Println(arr1, arr2, arr3, arr4)
// 二维数组
var arr5 = [3][5]int{{2: 3, 4: 5}, {1, 2, 3, 4}, {1, 2, 3, 4}}
fmt.Println(arr5)
}
package main
func main() {
var arr = [...]int{1, 2, 3, 4, 5, 6, 7}
// 方法1:for range
for index, value := range arr {
print("arr[", index, "]==", value, ",")
}
println()
// 方法2:fori
for index := 0; index < len(arr); index++ {
print("arr[", index, "]==", arr[index], ",")
}
}
package main
import "fmt"
func main() {
var arr1 = [3]int{1, 2, 3}
// 获取数组长度
fmt.Println(arr1, len(arr1))
// 获取元素
fmt.Println(arr1[0])
// 修改元素
arr1[0] = 101
fmt.Println(arr1)
}
package main
import (
"fmt"
)
func main() {
// 一维切片
// 方法1:声明并初始化一个切片
var slice1 []int
fmt.Println(slice1)
// 方法2:使用切片字面量初始化数组
var slice2 = []int{1, 2, 3, 4, 5, 6, 7}
fmt.Println(slice2)
// 方法3:使用make函数初始化
var slice3 = make([]int, 8)
fmt.Println(slice3)
// 方法4:通过数组创建切片,中括号中左开右闭(左侧不填默认为0,右侧不填默认数组长度)
var arr1 = [3]int{1, 2, 3}
slice4 := arr1[1:2]
fmt.Println(slice4)
// 方法5:通过切片创建切片
slice5 := slice2[:3]
fmt.Println(slice5)
// 方法6:拼接切片创建切片
slice6 := append(slice4, slice5...)
fmt.Println(slice6)
// 二维数组
var slice7 = [][]int{{2: 3, 4: 5}, {1, 2, 3, 4}, {1, 2, 3, 4}}
fmt.Println(slice7)
}
package main
func main() {
var slice1 = []int{1, 2, 3, 4, 5, 6, 7}
// 方法1:for range
for index, value := range slice1 {
print("arr[", index, "]==", value, ",")
}
println()
// 方法2:fori
for index := 0; index < len(slice1); index++ {
print("arr[", index, "]==", slice1[index], ",")
}
}
package main
import (
"fmt"
)
func main() {
var slice1 = []int{1, 2, 3, 4, 5, 6, 7}
// 切片长度,切片容量
fmt.Println(slice1, len(slice1), cap(slice1))
// 追加元素
slice1 = append(slice1, 8)
fmt.Println(slice1, len(slice1), cap(slice1))
// 修改元素
slice1[7] = 80
fmt.Println(slice1, len(slice1), cap(slice1))
// 拷贝切片
var slice2 = make([]int, len(slice1))
copy(slice2, slice1) // 深拷贝,可指定索引
slice3 := slice1 // 浅拷贝
slice1[6] = 70
fmt.Println(slice1, len(slice1), cap(slice1))
fmt.Println(slice2, len(slice2), cap(slice2))
fmt.Println(slice3, len(slice3), cap(slice3))
}
package main
import "fmt"
func main() {
// 方法1:声明一个Map
var map1 map[string]string
fmt.Println(map1)
// 方法2:使用map字面量初始化Map
var map2 = map[string]string{"name": "xumeng03"}
fmt.Println(map2)
// 方法3:使用make函数初始化
var map3 = make(map[string]string)
fmt.Println(map3)
}
package main
import "fmt"
func main() {
var map1 = map[string]string{"name": "xumeng03", "age": "23"}
for key, value := range map1 {
fmt.Println(key, value)
}
}
package main
import "fmt"
func main() {
var map1 = map[string]string{"name": "xumeng03"}
fmt.Println(map1)
// 获取值
fmt.Println(map1["name"])
// 添加值(如果值存在则为更新)
map1["age"] = "23"
fmt.Println(map1)
// 判断key是否存在
_, exits := map1["address"]
fmt.Println(exits)
// 删除
delete(map1, "age")
fmt.Println(map1)
// 长度
fmt.Println(len(map1))
}
package main
import "fmt"
func main() {
_m, _n, _result := add(1, 10)
fmt.Println(_m, _n, _result)
fmt.Printf("%T\n", add)
}
func add(m, n int) (_m, _n, _result int) {
result := 0
for i := m; i <= n; i++ {
result += i
}
return m, n, result
}
package main
import "fmt"
func main() {
// &表取地址,*表取值
a := 10
fmt.Printf("a的值是%d,a的数据类型是%T,a的地址是%p\n", a, a, &a)
p := &a
fmt.Printf("p的地址是%p,p的数据类型是%T,p地址的数据是%d\n", p, p, *p)
p1 := &p
fmt.Printf("p1的地址是%p,p1的数据类型是%T,p1地址的数据是%p\n", p1, p1, *p1)
}
package main
import "fmt"
func main() {
// 方法1:声明并初始化Person
var p1 Person = Person{}
p1.name = "xumeng03"
p1.age = 23
p1.sex = true
p1.address = "shanghai"
fmt.Println(p1)
// 方法2:使用字面量初始化Person
var p2 = Person{
"xumeng03", 23, true, "shanghai",
}
fmt.Println(p2)
// 方法3:使用字面量初始化Person部分属性
var p3 = Person{
name: "xumeng03",
}
fmt.Println(p3)
}
type Person struct {
name string
age int
sex bool
address string
}
package main
import "fmt"
func main() {
var j = JuniorHighStudent{
name: "xumeng02",
}
study(j, "物理")
var h = HighStudent{
name: "xumeng03",
}
study(h, "化学")
}
type IStudent interface {
study(name string) string
}
type HighStudent struct {
name string
}
type JuniorHighStudent struct {
name string
}
func (j JuniorHighStudent) study(name string) string {
return j.name + " study " + name
}
func (j HighStudent) study(name string) string {
return j.name + " study " + name
}
func study(iStudent IStudent, name string) {
fmt.Println(iStudent.study(name))
}
package main
import (
"fmt"
)
func main() {
a := 9
b := 3
fmt.Printf("%d + %d = %d\n", a, b, a+b)
fmt.Printf("%d - %d = %d\n", a, b, a-b)
fmt.Printf("%d * %d = %d\n", a, b, a*b)
fmt.Printf("%d / %d = %d\n", a, b, a/b)
fmt.Printf("%d %% %d = %d\n", a, b, a%b)
c := 3
c++
fmt.Printf("%d\n", c)
c--
fmt.Printf("%d", c)
}
package main
import (
"fmt"
)
func main() {
a := 9
b := 3
c := 3
fmt.Printf("%d > %d ? %t\n", a, b, a > b)
fmt.Printf("%d < %d ? %t\n", a, b, a < b)
fmt.Printf("%d == %d ? %t\n", a, b, a == b)
fmt.Printf("%d >= %d ? %t\n", b, b, b >= c)
fmt.Printf("%d <= %d ? %t\n", a, b, a <= b)
fmt.Printf("%d != %d ? %t\n", b, b, b != c)
}
func main() {
a := 9
b := 3
c := 3
fmt.Printf("%b & %d = %b\n", a, b, b, c, a > b && b == c)
fmt.Printf("%d < %d || %d == %d ? %t\n", a, b, b, c, a < b || b != c)
}
package main
import (
"fmt"
)
func main() {
a := 9
b := 3
// 对应位均为1,才是1,否则为0
fmt.Printf("%b & %b = %b\n", a, b, a&b)
// 对应位均为0,才是0,否则为1
fmt.Printf("%b | %b = %b\n\n", a, b, a|b)
// 对应位值不同为1,否则为0
fmt.Printf("%b ^ %b = %b\n", a, b, a^b)
// 按位取反
fmt.Printf("^%b = %b\n", a, ^a)
// 对于b的值,如果为0,则取a对应位的值,否则取0
fmt.Printf("%b &^ %b = %b\n", a, b, a&^b)
// a=a*2^2
a = a << 2
fmt.Printf("9 << 2 = %b(%d)\n", a, a)
// a=a/2
a = a >> 1
fmt.Printf("36 >> 1 = %b(%d)\n", a, a)
}
package main
import (
"fmt"
)
func main() {
a := 9
b := 3
a += b
fmt.Printf("9 + 3 = %d\n", a)
a -= b
fmt.Printf("12 - 3 = %d\n", a)
}
| 方法 | 说明 |
|---|---|
fmt.Print | 将参数打印输出到标准输出,不进行格式化处理,参数之间用空格分隔 |
fmt.Println | 将参数打印输出到标准输出,不进行格式化处理,参数之间用空格分隔,并在最后添加换行符 |
fmt.Printf | 通过格式化字符串和参数进行输出。格式化字符串中可以包含占位符(例如%s、%d等),用于指定参数的格式和位置 |
fmt.Sprintf | 通过格式化字符串和参数生成一个格式化后的字符串,而不是直接打印输出。返回生成的字符串,可以赋值给变量或作为其他函数的参数 |
package main
import "fmt"
func main() {
a := 11
fmt.Printf("类型: %T,值: %d,二进制值 %b,八进制值 %o,十进制值 %d,十六进制值 %x,十六进制值 %X\n", a, a, a, a, a, a, a)
b := "xumeng03"
fmt.Printf("类型: %T,值: %s\n", b, b)
c := 'A'
fmt.Printf("类型: %T,值: %c\n", c, c)
d := ""
fmt.Printf("类型: %T,地址: %p\n", d, &d)
}
| 方法 | 说明 |
|---|---|
fmt.Scan | 从标准输入中读取输入,并将解析后的值存储到指定的变量中。它需要传入指向变量的指针作为参数,并以空格为分隔符进行解析 |
fmt.Scanf | 从标准输入中按照指定的格式字符串读取输入,并将解析后的值存储到指定的变量中。 |
package main
import (
"fmt"
"strconv"
)
func main() {
//fmt.Print("请输入名称: ")
//var a string
//fmt.Scan(&a)
//fmt.Println("hello", a+"!")
fmt.Print("请输入名称、年龄: ")
var a string
var b int64
fmt.Scanf("%s %d", &a, &b)
fmt.Println("hello", a+" "+strconv.FormatInt(b, 10)+"!")
}
package main
import (
"fmt"
)
func main() {
fmt.Print("请输入年龄: ")
var b int64
//fmt.Scanf("%d", &b)
//if b > 18 {
// fmt.Print("成年")
//} else if b == 18 {
// fmt.Print("刚成年")
//} else {
// fmt.Print("未成年")
//}
if fmt.Scanf("%d", &b); b > 18 {
fmt.Print("成年")
} else if b == 18 {
fmt.Print("刚成年")
} else {
fmt.Print("未成年")
}
}
package main
import (
"fmt"
)
func main() {
fmt.Print("请输入季度: ")
var b int64
fmt.Scanf("%d", &b)
switch b {
case 1:
fmt.Println("第一季度")
case 2:
fmt.Println("第二季度")
case 3:
fmt.Println("第三季度")
case 4:
fmt.Println("第四季度")
default:
fmt.Println("未知季度")
}
}
package main
import (
"fmt"
)
func main() {
fmt.Print("请输入月份: ")
var b int64
fmt.Scanf("%d", &b)
switch {
case b >= 1 && b < 4:
fmt.Println("第一季度")
case b >= 4 && b < 7:
fmt.Println("第二季度")
case b >= 7 && b < 10:
fmt.Println("第三季度")
case b >= 10 && b < 12:
fmt.Println("第四季度")
default:
fmt.Println("未知季度")
}
}
package main
import (
"fmt"
)
func main() {
fmt.Print("请输入月份: ")
var b int64
fmt.Scanf("%d", &b)
switch b {
case 1, 2, 3:
fmt.Println("第一季度")
case 4, 5, 6:
fmt.Println("第二季度")
case 7, 8, 9:
fmt.Println("第三季度")
case 10, 11, 12:
fmt.Println("第四季度")
default:
fmt.Println("未知季度")
}
}
package main
import (
"fmt"
)
func main() {
fmt.Print("请输入月份: ")
var b int64
fmt.Scanf("%d", &b)
switch b {
case 1, 2, 3:
fmt.Println("第一季度")
fmt.Println("第一季度")
// 穿透case
fallthrough
case 4, 5, 6:
fmt.Println("第二季度")
fmt.Println("第二季度")
case 7, 8, 9:
fmt.Println("第三季度")
// 强制结束case
break
fmt.Println("第三季度")
case 10, 11, 12:
fmt.Println("第四季度")
default:
fmt.Println("未知季度")
}
}
package main
import (
"fmt"
)
func main() {
fmt.Print("请输入数字: ")
var b int
fmt.Scanf("%d", &b)
for a := 1; a <= b; a++ {
fmt.Println(a)
}
}
package main
import (
"fmt"
)
func main() {
fmt.Print("请输入数字: ")
var b int
fmt.Scanf("%d", &b)
//for a := 1; a <= b; a++ {
// fmt.Println(a)
//}
a := 1
// 相当于while循环
for a <= b {
fmt.Println(a)
a++
}
}
// 九九乘法表
package main
import "fmt"
func main() {
for a := 1; a < 10; a++ {
for b := 1; b <= a; b++ {
if b > 0 {
fmt.Print(" ")
}
fmt.Printf("%d*%d=%d", a, b, a*b)
}
fmt.Println()
}
}
// 水仙花数
package main
import "fmt"
func main() {
for a := 100; a < 1000; a++ {
b := a
result := 0
for ; b != 0; b = b / 10 {
c := b % 10
result += c * c * c
}
if result == a {
fmt.Println(a)
}
}
}
// 素数
package main
func main() {
count := 0
for a := 2; a <= 100; a++ {
var b = 2
for ; b < a; b++ {
if a%b == 0 {
break
}
}
if b == a {
println(a)
count++
}
}
println("总数:", count)
}
暂不介绍
函数也属于复合类型
package main
import "fmt"
func main() {
_m, _n, _result := add(1, 10)
fmt.Println(_m, _n, _result)
}
// 具名返回值可直接return
func add(m, n int) (_m, _n, _result int) {
result := 0
for i := m; i <= n; i++ {
result += i
}
return m, n, result
}
package main
import "fmt"
func main() {
fmt.Println(add1(1, 2, 100))
}
// 只能有一个,且必须是最后一个
func add1(m ...int) ([]int, int) {
result := 0
for _, v := range m {
result += v
}
return m, result
}
package main
import "fmt"
func main() {
fmt.Println("主函数。。。")
func() {
fmt.Println("匿名函数。。。")
}()
}
package main
import "fmt"
func main() {
fmt.Println("主函数。。。")
var fun = func() {
fmt.Println("匿名函数。。。")
}
fun()
fun()
}
package main
func main() {
println(fibonacci(12))
}
// fibonacci
func fibonacci(n int) (_result int) {
if n == 1 || n == 2 {
return 1
}
return fibonacci(n-1) + fibonacci(n-2)
}
package main
func main() {
println(nn(5))
}
func nn(n int) int {
if n == 1 {
return 1
}
return n * nn(n-1)
}
package main
func main() {
_, _, result := callback(1, 10, add)
print(result)
}
func add(m, n int) (_m, _n, _result int) {
result := 0
for i := m; i <= n; i++ {
result += i
}
return m, n, result
}
func callback(m, n int, fun func(int, int) (int, int, int)) (_m, _n, _result int) {
return fun(m, n)
}
将指定函数放入任务栈,延迟函数在父级函数return前执行(注意是延迟执行,不是延迟调用)
package main
func main() {
iprint(1)
iprint(2)
defer iprint(3)
iprint(4)
iprint(5)
defer iprint(6) // 1 2 4 5 6 3
}
func iprint(n int) {
println(n)
}
package main
import "fmt"
func main() {
result := add(10)
fmt.Println(result()) // 1
fmt.Println(result()) // 2
}
func add(n int) func() int {
result := n
return func() int {
result += 1
return result
}
}
package main
import "fmt"
func main() {
// &表取地址,*表取值
a := 10
fmt.Printf("a的值是%d,a的数据类型是%T,a的地址是%p\n", a, a, &a)
p := &a
fmt.Printf("p的地址是%p,p的数据类型是%T,p地址的数据是%d\n", p, p, *p)
p1 := &p
fmt.Printf("p1的地址是%p,p1的数据类型是%T,p1地址的数据是%p\n", p1, p1, *p1)
}
package main
import "fmt"
func main() {
a := [3]string{"xumeng03", "xumeng02", "xumeng01"}
b := [3]string{"xumeng03", "xumeng02", "xumeng01"}
c := [3]string{"xumeng03", "xumeng02", "xumeng01"}
fmt.Printf("a的值是%d,a的数据类型是%T,a的地址是%p\n", a, a, &a)
// 数组指针
p := &a
fmt.Printf("p的地址是%p,p的数据类型是%T,p地址的数据是%d\n", p, p, *p)
// 指针数组
var p1 = []*[3]string{&a, &b, &c}
fmt.Printf("p1的地址是%p,p1的数据类型是%T,p1地址的数据是%d\n", p1, p1, p1)
}
package main
import "fmt"
func main() {
// 函数指针
fmt.Printf("%p\n", a)
// 指针函数
i := b()
fmt.Printf("%p %v", i, i)
}
func a() {
fmt.Println("a...")
}
func b() *[4]int {
a := [4]int{1, 2, 3, 4}
fmt.Printf("%p\n", &a)
return &a
}
package main
func main() {
var n = 1
a(n)
println(n)
b(&n)
println(n)
}
func a(n int) {
n = 10
}
func b(p *int) {
*p = 10
}
结构体属于值类型
package main
import "fmt"
func main() {
// 方法1:声明并初始化Person
var p1 Person = Person{}
p1.name = "xumeng03"
p1.age = 23
p1.sex = true
p1.address = "shanghai"
fmt.Println(p1)
// 方法2:使用字面量初始化Person
var p2 = Person{
"xumeng03", 23, true, "shanghai",
}
fmt.Println(p2)
// 方法3:使用字面量初始化Person部分属性
var p3 = Person{
name: "xumeng03",
}
fmt.Println(p3)
}
type Person struct {
name string
age int
sex bool
address string
}
package main
import "fmt"
func main() {
var p1 = Person{
"xumeng03", 23, true, "shanghai",
}
fmt.Println(p1)
var pp1 *Person = &p1
// (*pp1).name = "Xumeng03"
pp1.name = "Xumeng03"
fmt.Println(p1, pp1)
var pp2 *Person = new(Person)
pp2 = &p1
// (*pp1).name = "Xumeng03"
pp2.age = 24
fmt.Println(p1, pp2)
}
type Person struct {
name string
age int
sex bool
address string
}
package main
import "fmt"
func main() {
// 匿名结构体
var s1 = struct {
name string
age int
}{"xumeng03", 23}
fmt.Println(s1, s1.name)
}
package main
import "fmt"
func main() {
// 匿名字段(一个类型只能有一个)
var s1 = struct {
string
int
}{"xumeng03", 23}
fmt.Println(s1, s1.string)
}
package main
import "fmt"
func main() {
//var p1 = Person{
// name: "xumeng03",
// age: 23,
// sex: true,
// address: Address{
// name: "shanghai",
// },
//}
var p1 = Person{
"xumeng03",
23,
true,
&Address{
name: "shanghai",
},
}
fmt.Println(p1)
}
type Person struct {
name string
age int
sex bool
//address Address
// 防止值传递
address *Address
}
type Address struct {
name string
}
package main
import "fmt"
func main() {
//var p1 = Person{
// name: "xumeng03",
// age: 23,
// sex: true,
// address: Address{
// name: "shanghai",
// },
//}
var p1 = Person{
"xumeng03",
23,
true,
}
fmt.Println(p1.hello("bilibili"))
}
type Person struct {
name string
age int
sex bool
}
func (p Person) hello(name string) string {
return p.name + "向 " + name + " 打招呼!"
}
package main
import "fmt"
func main() {
var p1 = Person{
"xumeng03",
23,
true,
}
fmt.Println(p1.hello("bilibili"))
var s1 = Student{
Person{
"xumeng03",
23,
true,
},
10010,
"眼眸流转",
"安阳师范学院",
}
fmt.Println(s1.name, s1.age, s1.hello("bilibili")) // 继承了Person的方法,如果Student中有与Person同名的方法或者属性,则为覆盖。
}
type Person struct {
name string
age int
sex bool
}
type Student struct {
Person
num int
name string
school string
}
func (p Person) hello(name string) string {
return p.name + "向 " + name + " 打招呼!"
}
package main
import "fmt"
func main() {
var j = JuniorHighStudent{
name: "xumeng02",
}
study(j, "物理")
var h = HighStudent{
name: "xumeng03",
}
study(h, "化学")
}
type IStudent interface {
study(name string) string
}
type HighStudent struct {
name string
}
type JuniorHighStudent struct {
name string
}
// 接口实现
func (j JuniorHighStudent) study(name string) string {
return j.name + " study " + name
}
// 接口实现
func (j HighStudent) study(name string) string {
return j.name + " study " + name
}
func study(iStudent IStudent, name string) {
fmt.Println(iStudent.study(name))
}
package main
import "fmt"
func main() {
var j = JuniorHighStudent{
name: "xumeng02",
}
study(j, "物理")
var h = HighStudent{
name: "xumeng03",
}
study(h, "化学")
}
type IStudent interface {
study(name string) string
}
// IStudent1 接口继承
type IStudent1 interface {
IStudent
study1(name string) string
}
type HighStudent struct {
name string
}
type JuniorHighStudent struct {
name string
}
// 接口实现
func (j JuniorHighStudent) study(name string) string {
return j.name + " study " + name
}
// 接口实现
func (j HighStudent) study(name string) string {
return j.name + " study " + name
}
func study(iStudent IStudent, name string) {
fmt.Println(iStudent.study(name))
}
package main
import (
"fmt"
"math"
)
func main() {
var t Shape = Triangle{3, 4, 5}
fmt.Println(t.Perimeter(), t.Area())
InterfaceType(&t)
var c Shape = Circle{5}
fmt.Println(c.Perimeter(), c.Area())
InterfaceType(&c)
var s Shape = Square{5}
fmt.Println(s.Perimeter(), s.Area())
InterfaceType(&s)
}
type Shape interface {
Perimeter() float64
Area() float64
}
// Triangle 三角形
type Triangle struct {
a, b, c float64
}
func (t Triangle) Perimeter() float64 {
return t.a + t.b + t.c
}
func (t Triangle) Area() float64 {
var p = t.Perimeter() / 2
return math.Sqrt(p * (p - t.a) * (p - t.b) * (p - t.c))
}
// Circle 圆形
type Circle struct {
r float64
}
func (c Circle) Perimeter() float64 {
return 2 * c.r * math.Pi
}
func (c Circle) Area() float64 {
return math.Pow(c.r, 2) * math.Pi
}
// Square 正方形
type Square struct {
s float64
}
func (s Square) Perimeter() float64 {
return 4 * s.s
}
func (s Square) Area() float64 {
return math.Pow(s.s, 2)
}
// InterfaceType 接口断言
func InterfaceType(shape *Shape) {
// 方法1
//if _, ok := (*shape).(Triangle); ok {
// fmt.Println("三角形")
//} else if _, ok := (*shape).(Circle); ok {
// fmt.Println("圆形")
//} else if _, ok := (*shape).(Square); ok {
// fmt.Println("正方形")
//} else {
// fmt.Println("未知形状")
//}
// 方法2
switch (*shape).(type) {
case Triangle:
fmt.Println("三角形")
case Circle:
fmt.Println("圆形")
case Square:
fmt.Println("正方形")
default:
fmt.Println("未知形状")
}
}
package main
func main() {
}
type V1 interface {
v1()
}
type V2 interface {
V1
v2()
}
type V3 interface {
V2
v3()
}
package main
import "fmt"
func main() {
var a iint = 100
// var b int = a
fmt.Println(a)
var aa mint = 100
var bb int = aa
fmt.Println(bb)
}
// 自定义类型
type iint int
// 类型别名
type mint = int
package main
import (
"fmt"
"os"
)
func main() {
open, err := os.Open("1.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(open.Name(), "open success!")
}
package main
import (
"fmt"
)
func main() {
err1 := prime(3)
if err1 != nil {
fmt.Println(err1)
return
}
fmt.Println("=====================")
err2 := prime(1)
if err2 != nil {
fmt.Println(err2)
return
}
}
func prime(n int) error {
if n < 2 {
// 方法1:errors.New
//err := errors.New("不合法数字!")
// 方法2:
err := fmt.Errorf("不合法数字!%d", 100)
return err
}
var i int
for i = 2; i < n; i++ {
if n%i == 0 {
break
}
}
if i >= n {
fmt.Println("是素数")
} else {
fmt.Println("不是素数")
}
return nil
}
package main
import (
"fmt"
"strconv"
)
func main() {
b, err := prime(1)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(b)
}
type PrimeError struct {
int
string
}
func (e PrimeError) Error() string {
return strconv.FormatInt(int64(e.int), 10) + "是非法数字!"
}
func prime(n int) (bool, *PrimeError) {
if n < 2 {
return false, &PrimeError{n, "非法数字"}
}
var i int
for i = 2; i < n; i++ {
if n%i == 0 {
break
}
}
if i >= n {
return true, &PrimeError{n, "是素数"}
} else {
return false, &PrimeError{n, "不是素数"}
}
}
package main
import "fmt"
func main() {
defer println("start")
fori(20)
defer println("end")
println("bilibili")
}
func fori(n int) {
defer func() {
if a := recover(); a != nil {
fmt.Println(a, "恢复运行")
}
}()
defer println("fori...start")
for i := 0; i < n; i++ {
fmt.Println(i)
if i == 10 {
// 恐慌,只有panic前所有defer都被执行后,panic才会被传递到调用处
panic("遇到了10!")
}
}
defer println("fori...end")
}
并发:同时处理多个任务(单处理器,也就是说一个时间点只做一件事,但是多个任务交替)
并行:同时执行多个任务(多处理器,也就是说一个时间点做多件事,多个任务同时进行)
不要使用共享内存的方式通信,而要以通信的方式共享内存!
协程执行的函数一般没有返回值,即是有也会被舍弃
package main
import "fmt"
func main() {
go iPrint("\tgoroutine1")
go iPrint("\tgoroutine2")
// 默认情况下主goroutine并不会等待其他goroutine执行完毕才结束
// 因此此处goroutine1和goroutine2有可能未执行完成
iPrint("主goroutine")
}
func iPrint(str string) {
for i := 0; i < 50; i++ {
fmt.Println(str, "打印", i)
}
}
package main
import (
"fmt"
)
// 无缓冲通道,读取和发送都会阻塞通道
var channel = make(chan string)
func push(str string) {
fmt.Println("开始发送数据")
channel <- str
fmt.Println("发送数据完成")
}
func pop() {
fmt.Println("开始读取数据")
fmt.Println(<-channel)
fmt.Println("读取数据完成")
}
func main() {
// 读取阻塞
//go push("xumeng03")
//pop()
// 发送阻塞
go pop()
go pop()
go pop()
push("xumeng01")
push("xumeng02")
push("xumeng03")
}
package main
import (
"fmt"
"strconv"
"time"
)
// 无缓冲通道,读取和发送都会阻塞通道,容量为0
var channel = make(chan string)
func main() {
go func() {
for i := 0; i < 10; i++ {
//time.Sleep(time.Second)
channel <- "xumeng" + strconv.Itoa(i)
fmt.Println("数据已压入通道", time.Now().Format("2006-01-02 15:04:05"))
}
// 关闭通道
close(channel)
}()
for s := range channel {
time.Sleep(time.Second)
fmt.Println(s, time.Now().Format("2006-01-02 15:04:05"))
}
}
package main
import (
"fmt"
"strconv"
"time"
)
// 缓冲通道,发送数据时若缓冲区已满则阻塞,接收数据若缓冲区为空则阻塞
var channel = make(chan string, 5)
func main() {
go func() {
for i := 0; i < 100; i++ {
channel <- "xumeng" + strconv.Itoa(i)
fmt.Println("数据已压入通道", time.Now().Format("2006-01-02 15:04:05"))
}
// 关闭通道
close(channel)
}()
for s := range channel {
time.Sleep(time.Second)
fmt.Println(s, time.Now().Format("2006-01-02 15:04:05"))
}
}
主要用于传参数参数类型,保护数据
package main
// 定向通道
var rchannel = make(<-chan string)
var wchannel = make(chan<- string)
func main() {
// 不可写入
//rchannel <- "111"
// 不可读取
//<-wchannel
}
package main
import "fmt"
func main() {
var channel = make(chan int)
go func() {
for i := 0; i < 100; i++ {
push(channel, i)
}
close(channel)
}()
for n := range channel {
fmt.Println(n)
}
}
func push(channel chan<- int, n int) {
channel <- n
}
func pop(channel <-chan int) {
fmt.Println(<-channel)
}
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
var c1 = make(chan int)
var c2 = make(chan int)
go func() {
rand.NewSource(time.Now().UnixNano())
time.Sleep(10 * time.Second)
c1 <- rand.Intn(100)
}()
go func() {
rand.NewSource(time.Now().UnixNano())
time.Sleep(10 * time.Second)
c2 <- rand.Intn(100)
}()
select {
case n := <-c1:
fmt.Println("c1", n)
case n := <-c2:
fmt.Println("c2", n)
case <-time.After(5 * time.Second):
fmt.Println("timeout!")
}
}
标准库 - Go 包:https://pkg.go.dev/std
func Print(a ...any) (n int, err error) 打印数据,不换行
package main
import "fmt"
func main() {
fmt.Print("hello world")
s1 := fmt.Sprint("hello world")
fmt.Print(s1)
fmt.Println("hello world")
s2 := fmt.Sprintln("hello world")
fmt.Print(s2)
}
func Printf(format string, a ...any) (n int, err error) 打印格式化数据
package main
import "fmt"
func main() {
a := 11
fmt.Printf("类型: %T,值: %d,二进制值 %b,八进制值 %o,十进制值 %d,十六进制值 %x,十六进制值 %X,地址 %p\n", a, a, a, a, a, a, a, &a)
a1 := fmt.Sprintf("类型: %T,值: %d,二进制值 %b,八进制值 %o,十进制值 %d,十六进制值 %x,十六进制值 %X,地址 %p", a, a, a, a, a, a, a, &a)
fmt.Println(a1)
s := "hello world"
fmt.Printf("类型: %T,值: %s,地址 %p\n", s, s, &s)
s1 := fmt.Sprintf("类型: %T,值: %s,地址 %p", s, s, &s)
fmt.Println(s1)
}
字符串相关函数
func Compare(a, b string) int 按字典顺序比较两个字符串, 如果 a == b,则结果为 0;如果 a < b,则结果为 -1;如果 a > b,则结果为 +1。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Compare("a", "b")) // -1
fmt.Println(strings.Compare("a", "a")) // 0
fmt.Println(strings.Compare("b", "a")) // 1
}
func Contains(s, substr string) bool 判断包含 substr 是否在 s 内
func ContainsAny(s, chars string) bool 判断s中是否包含chars中的任意一个字符
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Contains("seafood", "foo")) // true
fmt.Println(strings.Contains("seafood", "bar")) // false
fmt.Println(strings.Contains("seafood", "")) // true
fmt.Println(strings.Contains("", "")) // true
fmt.Println(strings.ContainsAny("team", "i")) // false
fmt.Println(strings.ContainsAny("fail", "ui")) // true
fmt.Println(strings.ContainsAny("ure", "ui")) // true
fmt.Println(strings.ContainsAny("failure", "ui")) // true
// chars是空字符串,因此没有任何字符可以在其中进行匹配。所以无论s是什么字符串,都不会在空字符串中存在匹配的字符
fmt.Println(strings.ContainsAny("foo", "")) // false
fmt.Println(strings.ContainsAny("", "")) // false
}
func Count(s, substr string) int 判断s中是否包含chars中的任意一个字符
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Count("cheese", "e")) // 3
// 如果 substr 为空字符串,则 Count 返回 1 + len(s)
fmt.Println(strings.Count("five", "")) // 5
}
func Cut(s, sep string) (before, after string, found bool) 在s中根据sep切割字符串并返回前、后、是否查询到切割字符
package main
import (
"fmt"
"strings"
)
func main() {
show := func(s, sep string) {
before, after, found := strings.Cut(s, sep)
fmt.Printf("%q, %q, %v\n", before, after, found)
}
show("Gopher", "Go") // "", "pher", true
show("Gopher", "ph") // "Go", "er", true
show("Gopher", "er") // "Goph", "", true
// 如未找到,after=s
show("Gopher", "Badger") // "Gopher", "", false
}
func CutPrefix(s, prefix string) (after string, found bool) 判断s是否以sep开头,如是则返回切割后结果,如不是则返回s
package main
import (
"fmt"
"strings"
)
func main() {
show := func(s, sep string) {
after, found := strings.CutPrefix(s, sep)
fmt.Printf("CutPrefix(%q, %q) = %q, %v\n", s, sep, after, found)
}
show("Gopher", "Go") // "pher", true
show("Gopher", "ph") // "Gopher", false
}
func CutSuffix(s, suffix string) (before string, found bool) 判断s是否以s结尾,如是则返回切割后结果,如不是则返回s
package main
import (
"fmt"
"strings"
)
func main() {
show := func(s, sep string) {
before, found := strings.CutSuffix(s, sep)
fmt.Printf("CutSuffix(%q, %q) = %q, %v\n", s, sep, before, found)
}
show("Gopher", "Go") // "Gopher", false
show("Gopher", "er") // "Goph", true
}
func EqualFold(s, t string) bool 判断s和t是否相等(忽略大小写)
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.EqualFold("Go", "go"))
fmt.Println(strings.EqualFold("AB", "ab")) // true
fmt.Println(strings.EqualFold("ß", "ss")) // false
}
func Fields(s string) []string 根据空格分隔s
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("Fields are: %q", strings.Fields(" foo bar baz ")) // ["foo" "bar" "baz"]
}
func HasPrefix(s, prefix string) bool 判断s是否以prefix 开头
func HasSuffix(s, suffix string) bool 判断s是否以suffix结尾
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.HasPrefix("Gopher", "Go")) // true
fmt.Println(strings.HasPrefix("Gopher", "C")) // false
fmt.Println(strings.HasPrefix("Gopher", "")) // true
fmt.Println(strings.HasSuffix("Amigo", "go")) // true
fmt.Println(strings.HasSuffix("Amigo", "O")) // false
fmt.Println(strings.HasSuffix("Amigo", "Ami")) // false
fmt.Println(strings.HasSuffix("Amigo", "")) //true
}
func Index(s, substr string) int返回 s 中第一个 substr 的索引,如果不存在,则返回 -1
func LastIndex(s, substr string) int 返回 s 中最后一个 substr 实例的索引,如果 s 中不存在 substr,则返回 -1
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Index("chicken", "ken")) // 4
// 未检索到,则返回-1
fmt.Println(strings.Index("chicken", "dmr")) // -1
fmt.Println(strings.LastIndex("go gopher", "go")) // 3
fmt.Println(strings.LastIndex("go gopher", "rodent")) // -1
}
func Join(elems []string, sep string) string 以sep作为分隔符,拼接string数组
package main
import (
"fmt"
"strings"
)
func main() {
s := []string{"foo", "bar", "baz"}
fmt.Println(strings.Join(s, ",")) // foo,bar,baz
}
func Repeat(s string, count int) string 返回一个重复count次的s字符串
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println("ba" + strings.Repeat("na", 2)) // banana
}
func Replace(s, old, new string, n int) string 在s中使用new替换old,最多替换n次
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2))
// n<0 则表示全局替换
fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))
}
func ReplaceAll(s, old, new string) string 在s中使用new替换所有old
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ReplaceAll("oink oink oink", "oink", "moo"))
}
func Split(s, sep string) []string 使用sep分割s,返回string数组
func SplitAfter(s, sep string) []string 使用sep分割s,返回string数组(保留分隔符)
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%q\n", strings.Split("a,b,c", ","))
fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ","))
}
func ToUpper(s string) string 将s转为大写
func ToLower(s string) string 将s转为小写
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ToUpper("Gopher"))
fmt.Println(strings.ToLower("Gopher"))
}
func Trim(s, cutset string) string 清除s中cutset中存在的字符
func TrimLeft(s, cutset string) string 清除s左侧所有中cutset中存在的字符,直至第一个非cutset中存在的字符
func TrimRight(s, cutset string) string 清除s右侧所有中cutset中存在的字符,直至第一个非cutset中存在的字符
func TrimSpace(s string) string 清楚s中空格、换行、制表符
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Print(strings.Trim("¡¡¡Hello, Gophers!!!", "!¡"))
fmt.Print(strings.TrimLeft("¡¡¡Hello, Gophers!!!", "!¡"))
fmt.Print(strings.TrimRight("¡¡¡Hello, Gophers!!!", "!¡"))
fmt.Println(strings.TrimSpace(" \t\n Hello, Gophers \n\t\r\n"))
}
基本类型的转换
func Atoi(s string) (int, error) 将字符串转为int
func Itoa(i int) string 将int转为字符串
package main
import (
"fmt"
"strconv"
)
func main() {
var a = 1
fmt.Println(strconv.Itoa(a))
var b = "10"
fmt.Println(strconv.Atoi(b))
}
func FormatInt(i int64, base int) string 将int转为string
func FormatFloat(f float64, fmt byte, prec, bitSize int) string 将float转为string
func FormatBool(b bool) string 将bool转为string
package main
import (
"fmt"
"strconv"
)
func main() {
var a int64 = 1
fmt.Println(strconv.FormatInt(a, 10))
var b = 3.14
fmt.Println(strconv.FormatFloat(b, 'g', -1, 64))
var c = true
fmt.Println(strconv.FormatBool(c))
}
func ParseInt(s string, base int, bitSize int) (i int64, err error) 将字符串解析为int
func ParseFloat(s string, bitSize int) (float64, error) 将字符串解析为float
func ParseBool(str string) (bool, error) 将字符串解析为bool
package main
import (
"fmt"
"strconv"
)
func main() {
var a = "1"
fmt.Println(strconv.ParseInt(a, 10, 64))
var b = "3.14"
fmt.Println(strconv.ParseFloat(b, 10))
var c = "true"
fmt.Println(strconv.ParseBool(c))
}
func Now() Time 获取当前时间
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now())
}
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time 获取指定的时间
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Date(2023, 10, 30, 22, 22, 22, 0, time.UTC))
fmt.Println(time.Date(2023, 10, 30, 22, 22, 22, 0, time.Local))
}
func (t Time) Format(layout string) string 格式化时间
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}
func Parse(layout, value string) (Time, error) 将字符串解析为时间
package main
import (
"fmt"
"time"
)
func main() {
var str = "2023-10-30 10:00:00"
parse, err := time.Parse("2006-01-02 15:04:05", str)
if err != nil {
fmt.Println(err)
}
fmt.Println(parse)
}
func (t Time) Date() (year int, month Month, day int) 获取时间的年月日
func (t Time) Clock() (hour, min, sec int) 获取时间的时分秒
package main
import (
"fmt"
"time"
)
func main() {
var t = time.Now()
year, month, day := t.Date()
hour, min, sec := t.Clock()
fmt.Println(year, month, day)
fmt.Println(hour, min, sec)
}
func (t Time) Year() int 获取时间的年份
func (t Time) Month() Month 获取时间的月份
func (t Time) Day() int 获取时间的日期
func (t Time) Hour() int 获取时间的小时
func (t Time) Minute() int 获取时间的分钟
func (t Time) Second() int 获取时间的秒钟
func (t Time) Nanosecond() int 获取时间的纳秒
func (t Time) YearDay() int 获取时间的在年份中的天数
func (t Time) Weekday() Weekday 获取时间是周几
package main
import (
"fmt"
"time"
)
func main() {
var t = time.Now()
fmt.Println("年份", t.Year())
fmt.Println("月份", t.Month())
fmt.Println("日期", t.Day())
fmt.Println("时", t.Hour())
fmt.Println("分", t.Minute())
fmt.Println("秒", t.Second())
fmt.Println("纳秒", t.Nanosecond())
fmt.Println("此年份第", t.YearDay(), "天")
fmt.Println("当天是", t.Weekday())
}
func (t Time) Unix() int64 获取时间距1970-1-1 00:00:00的时间差值(单位:秒)
func (t Time) UnixNano() int64 获取时间距1970-1-1 00:00:00的时间差值(单位:纳秒)
package main
import (
"fmt"
"time"
)
func main() {
var t = time.Now()
fmt.Println(t.Unix())
fmt.Println(t.UnixNano())
}
func (t Time) Add(d Duration) Time 在当前时间基础添加/减少时间
func (t Time) AddDate(years int, months int, days int) Time 在当前时间基础添加/减少日期
package main
import (
"fmt"
"time"
)
func main() {
var t = time.Now()
fmt.Println(t)
fmt.Println(t.Add(24 * time.Hour))
fmt.Println(t.AddDate(0, 1, 0))
fmt.Println(t.Add(-24 * time.Hour))
fmt.Println(t.AddDate(0, -1, 0))
}
func Sleep(d Duration) 沉睡指定时间
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now())
time.Sleep(3 * time.Second)
fmt.Println(time.Now())
}
func NewTimer(d Duration) *Timer 创建一个定时器,到达指定时间激活一次,timer.C为内部的无缓冲通道
package main
import (
"fmt"
"time"
)
func main() {
var timer = time.NewTimer(5 * time.Second)
//go func() {
// <-timer.C
// fmt.Println("这是5秒后啦")
//}()
//time.Sleep(10 * time.Second)
func() {
<-timer.C
fmt.Println("这是5秒后啦")
}()
}
package main
import (
"fmt"
"time"
)
func main() {
var timer = time.NewTimer(5 * time.Second)
go func() {
<-timer.C
fmt.Println("这是5秒后啦")
}()
time.Sleep(time.Second)
// 取消定时器
stop := timer.Stop()
if stop {
fmt.Println("计时器已停止!")
}
time.Sleep(10 * time.Second)
}
间隔指定时间激活一次
func NewTicker(d Duration) *Ticker 创建一个心跳,间隔指定时间激活一次,ticker.C为内部的无缓冲通道
package main
import (
"fmt"
"time"
)
func main() {
var ticker = time.NewTicker(2 * time.Second)
defer ticker.Stop()
var flag = make(chan bool)
go func() {
time.Sleep(10 * time.Second)
flag <- true
}()
for {
select {
case <-flag:
fmt.Println("结束程序!")
return
case <-ticker.C:
fmt.Println("定时器激活!")
}
}
}
func Join(elem ...string) string 拼接路径
package main
import (
"fmt"
"path"
)
func main() {
fmt.Println(path.Join("gostudy", "go.mod"))
}
func Split(path string) (dir, file string) 分割路径
package main
import (
"fmt"
"path"
)
func main() {
var p = "/root/GolandProjects/gostudy/go.mod"
fmt.Println(path.Split(p))
}
func Dir(path string) string 获取路径的目录部分
func Base(path string) string 获取路径的文件部分
func Ext(path string) string 获取路径的文件扩展名部分
package main
import (
"fmt"
"path"
)
func main() {
var p = "/root/GolandProjects/gostudy/go.mod"
fmt.Println(path.Dir(p))
fmt.Println(path.Base(p))
fmt.Println(path.Ext(p))
}
func Mkdir(name string, perm FileMode) error 创建目录,如父目录不存在则报错
func MkdirAll(path string, perm FileMode) error 创建目录,如父目录不存在则创建
// 注意这里使用的是windows!
package main
import (
"fmt"
"os"
)
func main() {
err := os.Mkdir("aaa", os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("make dir success!")
err1 := os.MkdirAll("aaa\\bbb\\cc", os.ModePerm)
if err1 != nil {
fmt.Println(err1)
return
}
fmt.Println("make dir success!")
}
func ReadDir(name string) ([]DirEntry, error) 读取文件夹
package main
import (
"fmt"
"os"
)
func main() {
dir, err := os.ReadDir("/Users/xumeng03/Downloads")
if err != nil {
fmt.Println(err)
return
}
for _, d := range dir {
if d.IsDir() {
fmt.Println(d.Name())
}
}
}
func Create(name string) (*File, error) 创建文件,如存在则会清空文件
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Create("a.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("create file success!", file)
}
func Stat(name string) (FileInfo, error) 获取文件信息
package main
import (
"fmt"
"os"
)
func main() {
stat, err := os.Stat("go.mod")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("文件名称:", stat.Name())
fmt.Println("文件大小:", stat.Size())
fmt.Println("文件模式:", stat.Mode())
fmt.Println("文件修改时间:", stat.ModTime())
fmt.Println("文件是否未目录:", stat.IsDir())
}
func Open(name string) (*File, error) 以O_RDONLY打开文件
func OpenFile(name string, flag int, perm FileMode) (*File, error) 以指定模式打开文件
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("a.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("open file success!", file)
err = file.Close()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("close file success!", file)
// os.O_RDONLY // 只读
// os.O_WRONLY // 只写
// os.O_RDWR // 读写
// os.O_APPEND // 往文件中添建(Append)
// os.O_CREATE // 如果文件不存在则先创建
// os.O_TRUNC // 文件打开时裁剪文件
// os.O_EXCL // 和O_CREATE一起使用,文件不能存在
// os.O_SYNC // 以同步I/O的方式打开
file, err = os.OpenFile("a.txt", os.O_WRONLY, os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("open file success!", file)
err = file.Close()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("close file success!", file)
}
func Remove(name string) error 移除文件,若为目录且目录下有文件,返回错误
package main
import (
"fmt"
"os"
)
func main() {
err := os.Remove("a.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("remove file success!")
}
func RemoveAll(path string) error 强制移除文件,忽略目录下是否有文件,慎用!
package main
import (
"fmt"
"os"
)
func main() {
err1 := os.MkdirAll("aaa\\bbb\\cc", os.ModePerm)
if err1 != nil {
fmt.Println(err1)
return
}
fmt.Println("make dir success!")
file, err := os.Create("aaa\\bbb\\cc\\a.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("create file success!", file)
err1 = file.Close()
if err1 != nil {
fmt.Println(err1)
return
}
err = os.RemoveAll("aaa\\bbb")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("remove file success!")
}
func Rename(oldpath, newpath string) error 重命名/移动文件
package main
import (
"fmt"
"os"
)
func main() {
err := os.Mkdir("aaa", 0777)
if err != nil {
fmt.Println(err)
return
}
_, err = os.Create("a.txt")
if err != nil {
fmt.Println(err)
return
}
err = os.Rename("a.txt", "aaa/aaa.txt")
if err != nil {
fmt.Println(err)
return
}
}
func Chmod(name string, mode FileMode) error 修改文件权限
package main
import (
"fmt"
"os"
)
func main() {
_, err := os.Create("a.txt")
if err != nil {
fmt.Println(err)
return
}
err = os.Chmod("a.txt", 0777)
if err != nil {
fmt.Println(err)
return
}
}
func Chown(name string, uid, gid int) error 修改文件所有者
package main
import (
"fmt"
"os"
)
func main() {
_, err := os.Create("a.txt")
if err != nil {
fmt.Println(err)
return
}
// os.Getuid():用户ID
// os.Getgid():组ID
fmt.Println(os.Getuid(), os.Getgid())
err = os.Chown("a.txt", os.Getuid(), os.Getgid())
if err != nil {
fmt.Println(err)
return
}
}
func (f *File) Read(b []byte) (n int, err error) 读取指定字节,到结尾读取数n=0,err=io.EOF
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("a.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("open success!", file)
defer file.Close()
for {
var buffer = make([]byte, 5, 5)
n, err := file.Read(buffer)
if err == io.EOF {
break
}
fmt.Println(string(buffer[:n]))
}
fmt.Println("read end")
}
func ReadFile(name string) ([]byte, error) 读取整个文件内容,只适合小文件!
package main
import (
"fmt"
"os"
)
func main() {
// ioutil.ReadFile
file, err := os.ReadFile("a.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(file))
}
func (f *File) Write(b []byte) (n int, err error) 写入byte数组到文件
package main
import (
"fmt"
"os"
)
func main() {
// 从开头开始写
//file, err := os.OpenFile("a.txt", os.O_RDWR, os.ModePerm)
// 追加内容
file, err := os.OpenFile("a.txt", os.O_RDWR|os.O_APPEND, os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
var b = []byte("hello world!")
n, err := file.Write(b)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(n)
}
func (f *File) WriteString(s string) (n int, err error) 写入字符串到文件
package main
import (
"fmt"
"os"
)
func main() {
// 从开头开始写
//file, err := os.OpenFile("a.txt", os.O_RDWR, os.ModePerm)
// 追加内容
file, err := os.OpenFile("a.txt", os.O_RDWR|os.O_APPEND, os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
n, err := file.WriteString("hello world!!!")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(n)
}
func (f *File) Seek(offset int64, whence int) (ret int64, err error) 设置光标位置
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Create("a.txt")
if err != nil {
fmt.Println(err)
return
}
n, err := file.WriteString("hello world!")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(n)
err = file.Close()
if err != nil {
fmt.Println(err)
return
}
file, err = os.OpenFile("a.txt", os.O_RDWR, os.ModePerm)
// io.SeekStart:文件开头
// io.SeekCurrent:当前位置
// io.SeekEnd:文件结尾
file.Seek(0, io.SeekCurrent)
n, err = file.WriteString("I'm xumeng03!")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(n)
}
func Truncate(name string, size int64) error 裁剪文件
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.OpenFile("a.txt", os.O_RDWR, os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
err = file.Truncate(8)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("truncate file success!")
}
package main
import (
"fmt"
"io"
"os"
)
func main() {
originfile, err := os.Open("a.txt")
if err != nil {
fmt.Println(err)
return
}
defer originfile.Close()
newfile, err1 := os.Create("b.txt")
if err1 != nil {
fmt.Println(err1)
return
}
defer newfile.Close()
for {
var b = make([]byte, 1024)
n, err := originfile.Read(b)
if err != nil && err != io.EOF {
fmt.Println(err)
return
}
fmt.Println("read byte:", n)
write, err1 := newfile.Write(b[:n])
if err1 != nil {
fmt.Println(err)
return
}
fmt.Println("write byte:", write)
if err == io.EOF {
break
}
}
fmt.Println("copy success!")
}
func Copy(dst Writer, src Reader) (written int64, err error) 复制文件
package main
import (
"fmt"
"io"
"os"
)
func main() {
originfile, err := os.Open("a.txt")
if err != nil {
fmt.Println(err)
return
}
defer originfile.Close()
newfile, err := os.Create("b.txt")
if err != nil {
fmt.Println(err)
return
}
defer newfile.Close()
written, err := io.Copy(newfile, originfile)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(written)
}
func (b *Reader) ReadBytes(delim byte) ([]byte, error) 逐行读取(bufio包下)
func (b *Reader) ReadString(delim byte) (string, error) 逐行读取(bufio包下)
package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
func main() {
file, err := os.Open("a.txt")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
//reader := bufio.NewReader(file)
//for {
// bytes, err := reader.ReadBytes('\n')
// if err != nil && err != io.EOF {
// fmt.Println(err)
// return
// }
// fmt.Println(strings.TrimSpace(string(bytes)))
// if err == io.EOF {
// break
// }
//}
reader := bufio.NewReaderSize(file, 1024)
for {
str, err := reader.ReadString('\n')
if err != nil && err != io.EOF {
fmt.Println(err)
return
}
fmt.Println(strings.TrimSpace(str))
if err == io.EOF {
break
}
}
}
func (b *Writer) Write(p []byte) (nn int, err error) 向文件写入byte数组
func (b *Writer) WriteString(s string) (int, error) 向文件写入字符串
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
file, err := os.OpenFile("a.txt", os.O_RDWR, os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
//writer := bufio.NewWriter(file)
//nn, err := writer.Write([]byte("hello world!"))
//if err != nil {
// fmt.Println(err)
// return
//}
//fmt.Println(nn)
writer := bufio.NewWriterSize(file, 1024)
nn, err := writer.WriteString("hello world!!!")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(nn)
writer.Flush()
}
从Go 1.16版本开始,ioutil包中的一些函数已被标记为不推荐使用,因为这些函数在处理大文件时可能会导致内存泄漏或性能问题。
func GOROOT() string 获取GOROOT路径
func NumCPU() int 获取内核数
func GOMAXPROCS(n int) int 设置go运行时最大可用CPU数
package main
import (
"fmt"
"runtime"
)
func main() {
// 获取GOROOT路径
fmt.Println(runtime.GOROOT())
// 获取系统
fmt.Println(runtime.GOOS)
// 获取内核数
fmt.Println(runtime.NumCPU())
}
func init() {
// 设置go运行时最大可用CPU数
runtime.GOMAXPROCS(runtime.NumCPU())
}
func Gosched() 主动让出执行权
package main
import (
"fmt"
"runtime"
)
func main() {
go func() {
for i := 0; i < 1000; i++ {
fmt.Println("\tgoroutine1:", i)
}
}()
for i := 0; i < 1000; i++ {
if i == 100 {
runtime.Gosched()
}
fmt.Println("goroutine0:", i)
}
}
func Goexit() 结束协程(如有defer函数仍会执行)
package main
import (
"fmt"
"runtime"
)
func main() {
go func() {
for i := 0; i < 1000; i++ {
fmt.Println("\tgoroutine1:", i)
if i == 100 {
runtime.Goexit()
}
}
}()
for i := 0; i < 1000; i++ {
fmt.Println("goroutine0:", i)
}
}
func (wg *WaitGroup) Add(delta int) 向同步等待组中添加正增量(需要在调用前增加计数)
func (wg *WaitGroup) Done() 向同步等待组中添加负增量
func (wg *WaitGroup) Wait() 等待同步等待组的计数器归零
package main
import (
"fmt"
"sync"
)
var waits = sync.WaitGroup{}
func main() {
waits.Add(1)
go iPrint("\tgoroutine1")
waits.Add(1)
go iPrint("\tgoroutine2")
iPrint("主goroutine")
waits.Wait()
fmt.Println("全部执行完成!")
}
func iPrint(str string) {
for i := 0; i <= 50; i++ {
fmt.Println(str, "打印", i)
}
waits.Done()
}
互斥锁:同一时间只有一个协程访问资源
当一个goroutine需要访问共享资源时,它会先调用Mutex的Lock方法来获取锁,如果锁已经被其他goroutine获取,则当前goroutine会被阻塞,直到锁被释放。因此,Mutex并不需要指定对谁加锁,它只需要保证同一时间只有一个goroutine可以获取锁即可
func (m *Mutex) Lock() 获取锁
func (m *Mutex) Unlock() 释放锁
package main
import (
"fmt"
"sync"
"time"
)
var l = sync.Mutex{}
var ticket = 10
func main() {
go iPrint("\tgoroutine1")
go iPrint("\tgoroutine2")
iPrint("主goroutine")
}
func iPrint(str string) {
for i := 0; i <= 10; i++ {
l.Lock()
if ticket > 0 {
time.Sleep(time.Second)
fmt.Println(str, "买出票:", ticket)
ticket--
l.Unlock()
} else {
l.Unlock()
break
}
}
}
读写锁:读的时候随便读,写的时候只能等
package main
import (
"fmt"
"sync"
"time"
)
var l = sync.RWMutex{}
var waits = sync.WaitGroup{}
func main() {
// 多个读操作可以同时进行
//waits.Add(1)
//go read("1")
//waits.Add(1)
//go read("2")
//waits.Add(1)
//go read("3")
//waits.Wait()
//fmt.Println("读取完成")
// 写操作同一时间点只能有一个在进行
//waits.Add(1)
//go write("1")
//waits.Add(1)
//go write("2")
//waits.Add(1)
//go write("3")
//waits.Wait()
//fmt.Println("写入完成")
// 读操作可以穿插,但是写操作不可被打断
waits.Add(1)
go read("1")
waits.Add(1)
go write("2")
waits.Add(1)
go read("3")
waits.Add(1)
go read("4")
waits.Wait()
fmt.Println("写入完成")
}
func read(str string) {
l.RLock()
fmt.Println(str, "开始读操作。。。")
time.Sleep(time.Second)
fmt.Println(str, "假装是一个读操作。。。")
fmt.Println(str, "结束读操作。。。")
l.RUnlock()
waits.Done()
}
func write(str string) {
l.Lock()
fmt.Println(str, "开始写操作。。。")
time.Sleep(5 * time.Second)
fmt.Println(str, "假装是一个写操作。。。")
fmt.Println(str, "结束写操作。。。")
l.Unlock()
waits.Done()
}
Go Mod:Go语言包管理工具
// 模块名称
module gostudy
// go最低版本
go 1.20
// 依赖
require (
github.com/bytedance/sonic v1.10.2 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.9.1 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.15.5 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.5.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
# 启用Go模块支持
go env -w GO111MODULE=on
# 配置Go模块代理GOPROXY
https://mirrors.aliyun.com/goproxy
# 初始化go.mod
go mod init 包名
# 下载包
go get -u github.com/gin-gonic/gin
# 清理未使用依赖包
go mod tidy
# 下载依赖
go mod download
# 更新包
go get -u
# 将依赖下载到项目中
go mod vendor
_导入包,并不使用该包中的任何函数、变量、类型,只会执行包中的init函数// 自定义包
package string
import "fmt"
func Count(arr []int) int {
return len(arr)
}
func count(arr []int) int {
return len(arr)
}
func init() {
fmt.Println("string init......")
}
使用自定义包
package main
// 导入包
import (
"fmt"
"golang/utils/string"
)
func main() {
var arr = []int{1, 2, 3, 4}
fmt.Println(string.Count(arr))
}
package main
import (
"fmt"
// 别名
. "golang/utils/string"
)
func main() {
var arr = []int{1, 2, 3, 4}
fmt.Println(Count(arr))
}
package main
import (
"fmt"
// 别名
str "golang/utils/string"
)
func main() {
var arr = []int{1, 2, 3, 4}
fmt.Println(str.Count(arr))
}
package main
import (
"fmt"
// 别名
_ "golang/utils/string"
)
func main() {
fmt.Println("main......")
}
待补。。。
package main
import (
"fmt"
"reflect"
)
func main() {
var f = 3.1415926
fmt.Println("type:", reflect.TypeOf(f), "value:", reflect.ValueOf(f))
value := reflect.ValueOf(f)
fmt.Println("type:", value.Kind())
fmt.Println("value:", value.Float())
}
package main
import (
"fmt"
"reflect"
)
func main() {
var person = Person{"xumeng03", 23}
get(person)
set(&person)
fmt.Println(person)
}
// 反射在设置结构体类型的属性时,只能设置被导出的属性!!!
type Person struct {
Name string
Age int
}
// 反射在获取结构体类型的方法时,只会返回被导出的方法!!!
func (p Person) Hello(str string) {
fmt.Println(p.Name, ": hello", str, "!")
}
func get(o interface{}) {
t := reflect.TypeOf(o)
fmt.Println(t.Name(), t.Kind())
v := reflect.ValueOf(o)
fmt.Println(v)
// 属性
fmt.Println("属性个数", t.NumField())
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
value := v.Field(i)
fmt.Println("属性名:", field.Name, "属性类型:", field.Type, "属性值:", value)
}
// 方法
fmt.Println("方法个数", t.NumMethod())
for i := 0; i < t.NumMethod(); i++ {
method := t.Method(i)
fmt.Println("方法名:", method.Name, "方法类型:", method.Type)
method.Func.Call([]reflect.Value{reflect.ValueOf(o), reflect.ValueOf("yanmou")})
}
}
func set(o interface{}) {
v := reflect.ValueOf(o)
elem := v.Elem()
name := elem.FieldByName("Name")
fmt.Println(v, "是否可以被修改:", name.CanSet())
name.SetString("xumeng33")
age := elem.FieldByName("Age")
fmt.Println(v, "是否可以被修改:", age.CanSet())
age.SetInt(24)
}
package main
import (
"fmt"
"reflect"
)
func main() {
var person = Person{"xumeng03", 23}
StructCall(person)
FuncCall(Hello)
}
// 反射在设置结构体类型的属性时,只能设置被导出的属性!!!
type Person struct {
Name string
Age int
}
// 反射在获取结构体类型的方法时,只会返回被导出的方法!!!
func (p Person) Hello(str string) {
fmt.Println(p.Name, ": hello", str, "!")
}
func Hello(str string) {
fmt.Println(str, ": hello!")
}
func StructCall(o interface{}) {
v := reflect.ValueOf(o)
fmt.Println(v.Kind(), v.Type())
// 调用对象的方法
f := v.MethodByName("Hello")
f.Call([]reflect.Value{reflect.ValueOf("yanmou")})
}
func FuncCall(f interface{}) {
v := reflect.ValueOf(f)
fmt.Println(v.Kind(), v.Type())
v.Call([]reflect.Value{reflect.ValueOf("xumeng03")})
}