• go语言基础操作--二


    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    a := 10
    	str := "mike"
    
    	//匿名函数,没有函数名字 形成一个闭包,函数定义,还没有调用
    	f1 := func() { //:=自动推到类型
    		fmt.Println("a= ", a)
    		fmt.Println("str = ", str)
    	}
    	f1()
    
    	//给一个函数类型起别名 这个写法不推荐
    	type FuncType func() //函数没有参数,内推返回值
    	//声明变量
    	var f2 FuncType
    	f2 = f1
    	f2()
    
    	//定义匿名函数,同时调用
    	func() {
    		fmt.Printf("a = %d, str = %s\n", a, str)
    	}() //后面的()代表此匿名函数
    
    	//带参数的匿名函数
    	f3 := func(i, j int) {
    		fmt.Printf("i = %d , j = %d\n", i, j)
    	}
    	f3(1, 2)
    
    	//定义匿名函数,同时调用
    	func(i, j int) {
    		fmt.Printf("i = %d , j = %d\n", i, j)
    	}(10, 20)
    
    	//匿名函数,有参有返回值
    	x, y := func(i, j int) (max, min int) {
    		if i > j {
    			max = i
    			min = j
    		} else {
    			max = j
    			min = i
    		}
    		return
    	}(10, 20)
    	fmt.Printf("x = %d, y = %d\n", x, y)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    //闭包捕获外部变量的特点
    	a := 10
    	str := "mike"
    	func() {
    		//闭包以引用方式
    		a = 666
    		str = "go"
    		fmt.Printf("内部:a = %d, str = %s\n", a, str)
    	}() //()外部直接调用
    	fmt.Printf("外部:a = %d, str = %s\n", a, str) //外部同步
    	//内部:a = 666, str = go
    	//	外部:a = 666, str = go
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    它不关心这些捕获了的变量和常量是否已经超出作用域,所以只有闭包还在使用它,这些变量就还会存在

    // 函数的返回值是一个匿名函数,返回一个函数类型
    func testUnKoun() func() int {
    	var x int //没有初始化,值为0
    
    	return func() int {
    		x++
    		return x * x //函数调用完毕 x自动释放
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    f := testUnKoun()
    fmt.Println(f()) //1
    fmt.Println(f()) //4
    fmt.Println(f()) // 9
    fmt.Println(f()) // 16
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我们看到的声明周期不由它的作用域决定,变量x仍然隐式的存在于f中

    函数调用定义

    // 无参无返回值
    func MyFunc() {
    	a := 666
    	fmt.Println("a= ", a)
    }
    
    // 有参无返回值
    // 参数传递,只能由实参传递给形参,不能反过来,单向传递
    func MyFunc1(a int) { //定义函数,在()中定义的参数叫形参
    	//a = 111
    	fmt.Println("aa = ", a)
    }
    
    func MyFunc2(a int, b int) { //定义函数,在()中定义的参数叫形参 简单写法func MyFunc2(a,b int)
    	//a = 111
    	fmt.Printf("a= %d, b = %d \n", a, b)
    }
    
    func MyFunc3(a int, b string, c float64) {
    	fmt.Printf("a=%d, b = %s,c = %f\n", a, b, c)
    }
    
    // 不定参数类型 ...type 不定参数,只能放在形参中的最后一个参数
    func MyFunc4(args ...int) { //传递的实参可以是0或者多个
    	fmt.Println("len(args) = ", len(args)) //获取用户传递参数的个数
    	for i := 0; i < len(args); i++ {
    		fmt.Printf("args[%d] = %d\n", i, args[i])
    	}
    }
    func main01() {
    	MyFunc()
    	MyFunc1(11) //实参
    	MyFunc2(666, 777)
    	MyFunc3(11, "aaa", 3.14)
    	MyFunc4(1, 2, 3)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    // 固定参数一定要传参,不定参数根据需求传参 不定参数类型 ...type 不定参数,只能放在形参中的最后一个参数
    func MyFunc5(a int, args ...int) { //传递的实参可以是0或者多个
    
    }
    
    func myFunc01(tmp ...int) {
    	for _, data := range tmp {
    		fmt.Println("data = ", data)
    	}
    }
    func myFunc02(tmp ...int) {
    	for _, data := range tmp {
    		fmt.Println("data = ", data)
    	}
    }
    
    // 不定参数的传递
    func test(args ...int) {
    	//全部元素传递给myFunc01
    	myFunc01(args...)
    	fmt.Println("================")
    	//只想把后2个参数传递给另外一个函数使用
    	myFunc02(args[:2]...) //0~2(不包括数字2),触底传递过去 1 2
    	myFunc02(args[2:]...) //从args[2]开始(包括本身),把后面所有元素传递过去 3 4
    }
    
    // 无参有返回值 只有一个返回值
    // 有返回值的函数需要通过return中断函数,通过return返回
    func myfunc01() int {
    	return 666
    }
    
    // 给返回值起一个变量名,go推荐写法 常用写法
    func myfunc02() (result int) {
    	//return 666
    	result = 666
    	return
    }
    
    // 多个返回值
    func myfunc03() (int, int, int) {
    	return 1, 2, 3
    }
    
    // go官方推荐写法
    func myfunc04() (a int, b int, c int) {
    	a, b, c = 111, 222, 333
    	return
    }
    
    // 有参有返回值
    func MaxAndMin(a, b int) (max, min int) {
    	if a > b {
    		max = a
    		min = b
    	} else {
    		max = b
    		min = a
    	}
    	return
    }
    
    func funcb() (b int) {
    	b = 222
    	fmt.Println("funcb b = ", b)
    	return
    }
    
    // 普通函数的调用流程
    func funca() (a int) {
    	a = 111
    
    	b := funcb()
    	fmt.Println("funca b = ", b)
    	//调用另外一个函数
    	fmt.Println("funca a = ", a)
    	return
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    main()

    //MyFunc5(111, 1, 2, 3)
    	//test(1, 2, 3, 4)
    	//var a int
    	//a = myfunc01()
    	//fmt.Println("a = ", a)
    	//b := myfunc01()
    	//fmt.Println("b = ", b)
    	//
    	//c := myfunc02()
    	//fmt.Println("c = ", c)
    	//
    	//a, b, c = myfunc03()
    	//fmt.Println(a, b, c)
    	//
    	//a, b, c = myfunc04()
    	//fmt.Println(a, b, c)
    
    	//max, min := MaxAndMin(10, 20)
    	//fmt.Println(max, min)
    	/**
    	main func
    	funcb b =  222
    	funca b =  222
    	funca a =  111
    	main a =  111
    	*/
    	//fmt.Println("main func")
    	//a := funca()
    	//fmt.Println("main a = ", a)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    递归函数实现

    // 函数递归调用的流程
    func testRecursion(a int) { //函数调用终止调用的条件,非常重要
    
    	if a == 1 {
    		fmt.Println("a = ", a)
    		return
    	}
    	//函数调用自身
    	testRecursion(a - 1)
    	fmt.Println("a = ", a)
    }
    
    // 数字累加
    func InteragerSum() (sum int) {
    	for i := 0; i <= 100; i++ {
    		sum += i
    	}
    	return
    }
    
    func InteragerSum1(i int) int {
    
    	if i == 1 {
    		return 1
    	}
    	return i + InteragerSum1(i-1)
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    main方法

    //testRecursion(3)
    
    //var sum int
    sum = InteragerSum()
    //sum = InteragerSum1(100)
    //fmt.Println("sum = ", sum)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    回调函数

    // 起别名
    type funcType func(int, int) int
    
    // 实现加法
    func Add(a, b int) int {
    	return a + b
    }
    
    func Minus(a, b int) int {
    	return a - b
    }
    
    func Mul(a, b int) int {
    	return a * b
    }
    
    // 回调函数,函数参数是函数类型,这个函数就是回调函数
    // 计算器可以进行四则运算 多态,多种形态 调用同一个接口,不同的表现,可以实现不同表现,加减乘除
    func Calc(a, b int, fTest funcType) (result int) {
    	fmt.Println("Calc")
    	result = fTest(a, b) // 这个函数还没有实现
    	//result = Add(a,b) // Add必须定义后,才能调用
    	return
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    main方法

    //a := Calc(1, 1, Add)
    //fmt.Println("a = ", a)
    
    • 1
    • 2
    // 形成了一个独立的空间
    func testClouse() int {
    	//函数被调用时,x才分配空间,才初始化为0
    	var x int //没有初始化值为0
    	x++
    	return x * x //函数调用完毕 x自动释放
    }
    
    // 函数的返回值是一个匿名函数,返回一个函数类型
    func testUnKoun() func() int {
    	var x int //没有初始化,值为0
    
    	return func() int {
    		x++
    		return x * x //函数调用完毕 x自动释放
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    main方法

    //返回值为一个匿名函数,返回一个函数类型,通过f来调用返回的匿名函数,f来调用闭包函数
    f := testUnKoun()
    fmt.Println(f()) //1
    fmt.Println(f()) //4
    fmt.Println(f()) // 9
    fmt.Println(f()) // 16
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    defer调用

    /**
    	defer作用,关键字defer用户延迟一个函数或者方法(或者当前所创建的匿名函数)的执行。注意
    	defer语句只能出现在函数或方法的内部。
    	*/
    
    	//defer 延迟调用 main函数结束前调用
    	defer fmt.Println("bbbbbbbbbb")
    
    	fmt.Println("aaaaaaaaaa")
    	//aaaaaaaaaa
    	//bbbbbbbbbb
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    多个defer执行顺序

    如果一个函数中有多个defer语句,它们会以LIFO(后进先出)的顺序执行,哪怕函数或某个延迟调用发生错误,这些调用依旧会被执行。

    /*
    *
    defer语句经常被用于处理成对的操作,如打开,关闭,连接,断开连接
    加锁,释放锁。通过defer机制,不论函数逻辑多复杂,都能保证在任何执行路径下,
    资源被释放。释放资源的defer应该直接跟在请求资源的语句后。
    */
    
    func test(x int) {
    	sum := 100 / x
    	fmt.Println(sum)
    }
    
    func main() {
    	bbbbbbbbbbb
    	aaaaaaaaaaa
    	//defer fmt.Println("aaaaaaaaaaa")
    	//defer fmt.Println("bbbbbbbbbbb")
    	调用一个函数,导致内存出问题
    	//test(0) //这个会先调用
    	//defer fmt.Println("ccccccccccc")
    
    
    	//ccccccccccc
    	//bbbbbbbbbbb
    	//aaaaaaaaaaa
    	defer fmt.Println("aaaaaaaaaaa")
    	defer fmt.Println("bbbbbbbbbbb")
    	//调用一个函数,导致内存出问题
    	defer test(0) //
    	defer fmt.Println("ccccccccccc")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    defer和匿名函数结合使用

    package main
    
    import "fmt"
    
    func main01() {
    	a := 10
    	b := 20
    
    	defer func() {
    		fmt.Println(a, b)
    	}()
    
    	a = 111
    	b = 222
    	fmt.Println(a, b) /// 111 222
    }
    
    func main() {
    	a := 10
    	b := 20
    
    	defer func(a, b int) {
    		fmt.Println(a, b)
    	}(a, b) // 10 20 把参数传递过去 已经先传递参数,只是没有调用
    
    	a = 111
    	b = 222
    	fmt.Println(a, b) /// 111 222
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    获取命令行参数

    package main
    
    import (
    	"fmt"
    	"os"
    )
    
    // 获取命令行参数
    func main() {
    
    	//接收用户传递的参数,都是以字符串方式传递的
    	list := os.Args
    	n := len(list)
    	fmt.Println("n = ", n)
    
    	for i := 0; i < n; i++ {
    		fmt.Printf("list[%d] = %s\n", i, list[i])
    	}
    
    	for i, data := range list {
    		fmt.Printf("list[%d] = %s\n", i, data)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述

    局部变量

    package main
    
    import "fmt"
    
    func test() {
    	a := 10
    	fmt.Println("a = ", a)
    }
    
    func main() {
    	//定义在{}里面的变量就是局部变量,只能在{}里面有效
    	// 执行执行到定义变量那句话,才开始分配空间,离开作用域自动释放
    	//作用域,变量起作用的范围
    	{
    		i := 10
    		fmt.Println("i = ", i)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    全局变量

    package main
    
    import "fmt"
    
    func test() {
    	fmt.Println("test = ", a)
    }
    
    // 定义在函数外部的变量是全局变量 全部变量在任何地方都能使用
    var a int
    
    // a := 10 没有这样的写法
    func main() {
    	//全局变量
    	a = 10
    	fmt.Println("a = ", a)
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    不同作用域的同名变量

    package main
    
    import "fmt"
    
    var a byte //全局变量
    
    func main() {
    	//不同作用域的同名变量
    	//不同作用域,允许定义同名变量
    	//使用变量的原则,就近原则
    	var a int             //局部量
    	fmt.Printf("%T\n", a) //int
    
    	{
    		var a float32
    		fmt.Printf("2: %T\n", a) //float32
    	}
    
    	test()
    }
    
    func test() {
    	fmt.Printf("3: %T\n", a) //uint8
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    工作区介绍

    导入包
    import "fmt" //1
    import . "fmt" //2
    import io "fmt" //给包名起别名
    import(
    "fmt"
    "os"
    )
    import _ "fmt" //忽略此包
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    工程管理

    1 分文件编程(多个源文件),必须放在src目录
    2 设置GOPATH环境变量

    init函数

    import _“fmt” _操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的init函数

  • 相关阅读:
    [黑马程序员Pandas教程]——DataFrame数据的增删改操作
    VBA之正则表达式(36)-- 提取年份范围
    Essential C++ 编程基础
    虚拟机配置网络ip,主打一个详细
    在线地图获取城市路网数据
    使用 Docker 部署 Answer 问答平台
    14.抽象工厂模式
    聊聊 React 中被低估的 useSyncExternalStore Hooks
    C---结构体
    用vite搭建一个vue3 + ts项目
  • 原文地址:https://blog.csdn.net/qq_40432598/article/details/132639828