• Day_02


    1.无参数无返回值函数的使用

    package main
    
    import "fmt"
    
    //无参无返回值函数的定义
    func MyFunc() {
    	a := 666
    	fmt.Println("a= ", a)
    }
    
    func main() {
    	//无参无返回值函数的调用,函数名()
    	MyFunc()
    }
    

     2.普通参数列表

    package main
    
    import "fmt"
    
    //有参无返回值函数的定义,普通参数列表
    func MyFunc01(a int) {
    	//a = 111
    	fmt.Println("a = ", a)
    }
    
    //传递多个参数
    func MyFunc02(a int, b int) {
    	fmt.Printf("a = %d,b = %d
    ", a, b)
    }
    
    func MyFunc03(a, b int) {
    	fmt.Printf("a = %d,b = %d
    ", a, b)
    }
    
    func MyFunc04(a int, b string, c float64) {
    
    }
    
    func MyFunc05(a, b string, c float64, d, e int) {
    
    }
    
    func main() {
    	MyFunc01(666)
    	MyFunc02(123, 456)
    	MyFunc03(888, 999)
    }
    

     3.不定参数类型

    package main
    
    import "fmt"
    
    //...int类型这样的类型,...type不定参数类型
    //不定参数一定只能放在形参中的最后一个参数
    func MyFunc01(args ...int) { //传递的参数可以是0个或多个
    	fmt.Printf("传递了%d个参数
    ", len(args)) //获取用户传递参数的数量
    
    	//不定参数数量返回的是一个列表,所以我们可以用for循环将获取其值
    	for i := 0; i < len(args); i++ {
    		fmt.Printf("args[%d] = %d
    ", i, args[i])
    	}
    	fmt.Println("========================================")
    	//也可以用这种方式,返回2个值,第一个是下标,第二个是下标所对应的数
    	for i, data := range args {
    		fmt.Printf("第二种方式:args[%d] = %d
    ", i, data)
    	}
    }
    
    func main() {
    	MyFunc01()
    	fmt.Println("++++++++++++++++++++++++++++++++++")
    	MyFunc01(1)
    	fmt.Println("++++++++++++++++++++++++++++++++++")
    	MyFunc01(1, 2, 3)
    }
    

     4.不定参数传递

    package main
    
    import "fmt"
    
    func myfunc(tmp ...int) {
    	for _, data := range tmp {
    		fmt.Println("data = ", data)
    	}
    	fmt.Println("我是myfunc+++++++++")
    }
    
    func myfunc2(tmp ...int) {
    	for _, data := range tmp {
    		fmt.Println("data = ", data)
    	}
    	fmt.Println("我是myfunc2+++++++++")
    }
    
    func test(args ...int) {
    	//全部元素传递给myfunc
    	myfunc(args...)
    	//只想把后2个参数传递给另外一个函数使用
    	//myfunc2(args[:2]...)	//从args[0]~args[2](不包括args[2]),传递过去
    	myfunc2(args[2:]...) //从args[2]开始(包括本身),把后面所有元素传递过去
    }
    
    func main() {
    	test(1, 2, 3, 4)
    
    }
    

     5.一个返回值

    package main
    
    import "fmt"
    
    //无参有返回值;只有一个返回值
    //有返回值的函数需要通过return中断函数,通过return返回
    func myfunc01() int {
    	return 666
    }
    
    //给返回值起一个变量名,go推荐写法,也是常用写法
    func myfunc02() (result int) {
    	result = 777
    	return
    }
    
    func main() {
    	//无参有返回值函数调用,定义一个变量接收返回值
    	var a = myfunc01()
    	fmt.Println("a", a)
    
    	b := myfunc01()
    	fmt.Println("b= ", b)
    
    	c := myfunc02()
    	fmt.Println("c= ", c)
    
    }
    

     6.多个返回值

    package main
    
    import "fmt"
    
    //多个返回值
    func myfunc01() (int, int, int) {
    	return 1, 2, 3
    }
    
    //Go官方推荐写法
    func myfunc02() (a int, b int, c int) {
    	a, b, c = 111, 222, 333
    	return
    }
    
    func myfunc03() (a, b, c int) {
    	a, b, c = 444, 555, 666
    	return
    }
    
    func main() {
    	//函数调用
    	a, b, c := myfunc03()
    	fmt.Printf("a = %d,b = %d,c = %d
    ", a, b, c)
    }
    

     7.有参数有返回值

    package main
    
    import "fmt"
    
    //函数定义
    func MaxAndMin(a, b int) (max, min int) {
    	if a > b {
    		max = a
    		min = b
    	} else {
    		max = b
    		min = a
    	}
    	return //有返回值的函数,必须通过return返回
    }
    
    func main() {
    	max, min := MaxAndMin(50, 10)
    	fmt.Printf("最大值是:%d,最小值是:%d
    ", max, min)
    
    	//通过匿名变量丢弃某个返回值
    	i, _ := MaxAndMin(50, 10)
    	fmt.Printf("i = %d", i)
    
    }
    

     8.普通函数的调用流程

    package main
    
    import "fmt"
    
    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 //返回
    }
    
    func main() {
    	fmt.Println("main  func")
    	a := funca()
    	fmt.Println("main a = ", a)
    }
    

     9.函数递归的调用流程

    package main
    
    import "fmt"
    
    func test(a int) {
    	if a == 1 { //函数终止调用的条件,非常重要
    		fmt.Println("a = ", a)
    		return //终止函数调用
    	}
    	//函数调用自身
    	test(a - 1)
    	fmt.Println("a = ", a)
    }
    
    func main() {
    	test(3)
    	fmt.Println("main")
    }
    

     10.通过递归实现的累加

    package main
    
    import "fmt"
    
    //普通方式实现累加
    func test01() (sum int) {
    	for i := 1; i <= 100; i++ {
    		sum += i
    	}
    	return
    }
    
    //递归方式实现累加(递减)
    func test02(i int) int {
    	if i == 1 {
    		return 1
    	}
    	return i + test02(i-1)
    }
    
    //递归方式实现累加(递增)
    func test03(i int) int {
    	if i == 100 {
    		return 100
    	}
    	return i + test03(i+1)
    }
    
    func main() {
    	var sum int
    	//sum = test01()
    	//sum = test02(100)
    	sum = test03(1)
    	fmt.Println("sum = ", sum)
    
    }
    

     11.函数类型

    package main
    
    import "fmt"
    
    func Add(a, b int) int {
    	return a + b
    }
    
    func Minus(a, b int) int {
    	return a - b
    }
    
    //函数也是一种数据类型,通过type给一个函数类型起名
    //FuncType它是一种函数类型
    type FuncType func(int, int) int //没有函数名字,没有{}
    
    func main() {
    	var result int
    	result1 = Add(5, 1) //传统调用方式
    	fmt.Println("result1 = ", result1)
    
    	//声明一个函数类型的变量,变量名叫fTest
    	var fTest FuncType
    	fTest = Add             //是变量就可以赋值
    	result2 = fTest(10, 20) //等价于Add(10,20)
    	fmt.Println("result2 = ", result2)
    
    }
    

     12.回调函数

    package main
    
    import "fmt"
    
    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
    
    }
    
    func main() {
    	a := Calc(10, 5, Mul) //那么在这里我想实现减法,我在上面定义一下,然后拿到这里修改一下Add为Minus就可以了,类似的乘法,除法同理,有利于程序的扩展
    	fmt.Println("a = ", a)
    }
    

     13.匿名函数和闭包

    package main
    
    import "fmt"
    
    func main() {
    	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
    ", a, str)
    	}() //后面的括号代表调用此匿名函数
    
    	//带参数的匿名函数
    	f3 := func(i, j int) {
    		fmt.Printf("i = %d,j = %d
    ", i, j)
    	}
    	f3(1, 2)
    
    	//定义匿名函数,同时调用
    	func(i, j int) {
    		fmt.Printf("i = %d,j = %d
    ", 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
    	}(50, 20)
    	fmt.Printf("x = %d,y = %d
    ", x, y)
    }
    

     14.闭包捕获外部变量的特点

    package main
    
    import "fmt"
    
    func main() {
    	a := 10
    	str := "Mike"
    
    	func() {
    		//闭包以引用方式捕获外部变量
    		a = 666
    		str = "go"
    		fmt.Printf("内部:a = %d,str = %s
    ", a, str)
    	}() //()代表直接调用
    	fmt.Printf("外部:a = %d,str = %s
    ", a, str)
    }
    
    /*
    打印结果:
    内部:a = 666,str = go
    外部:a = 666,str = go
    */
    

     15.闭包的特点

    package main
    
    import "fmt"
    
    //函数的返回值是一个匿名函数,返回一个函数类型
    func test02() func() int {
    	var x int //没有初始化,值为0
    
    	return func() int {
    		x++
    		return x * x
    	}
    }
    
    func main() {
    	//返回值为一个匿名函数,返回一个函数类型,通过f来调用返回的匿名函数,f来调用闭包函数
    	//它不关心这些捕获了的变量和常量是否已经超出了作用域
    	//所以只有闭包还在使用它,这些变量就还会存在。
    	f := test02()
    	fmt.Println(f) //1
    	fmt.Println(f) //4
    	fmt.Println(f) //9
    	fmt.Println(f) //16
    	fmt.Println(f) //25
    }
    
    func test01() int {
    	//函数被调用时,x才分配空间,才初始化为0
    	var x int //没有初始化,值为0
    	x++
    	return x * x //函数调用完毕,x自动释放
    
    }
    
    func main01() {
    	fmt.Println(test01())
    	fmt.Println(test01())
    	fmt.Println(test01())
    	fmt.Println(test01())
    
    }
    

     16.defer的使用

    package main
    
    import "fmt"
    
    /*
    	关键字defer用于延迟一个函数或者方法(或者当前所创建的匿名函数)的执行,
    	defer语句只能出现在函数或方法的内部。
    */
    
    func main() {
    	//defer延迟调用 在函数结束前调用,所以可以看到aaaaaaaa先打印
    	defer fmt.Println("bbbbbbbbbbbbbbbbbbbb")
    	fmt.Println("aaaaaaaaaaaaaaaaaaaa")
    
    }
    
    /*
    运行结果:
    aaaaaaaaaaaaaaaaaaaa
    bbbbbbbbbbbbbbbbbbbb
    */
    

     17.多个defer的执行顺序

    package main
    
    import "fmt"
    
    /*
    如果一个函数中有多个defer语句,他们会以为LIFO(后进先出)的顺序执行,哪怕函数或某个延迟调用发生错误,这些调用依旧会被执行。
    */
    
    func test(x int) {
    	result := 100 / x
    	fmt.Println("result = ", result)
    }
    
    func main() {
    
    	defer fmt.Println("aaaaaaaaaaaaaaaaaaaa")
    	defer fmt.Println("bbbbbbbbbbbbbbbbbbbb")
    
    	//调用一个函数,导致内存出问题,故意让除以0
    	defer test(0)
    	defer fmt.Println("ccccccccccccccccc")
    }
    
    /*
    运行结果:
    ccccccccccccccccc
    bbbbbbbbbbbbbbbbbbbb
    aaaaaaaaaaaaaaaaaaaa
    panic: runtime error: integer divide by zero
    
    goroutine 1 [running]:
    main.test(0x0)
            D:/Let's  Go/17_多个defer的执行顺序.go:6 +0xd9
    main.main()
            D:/Let's  Go/17_多个defer的执行顺序.go:18 +0x15e
    exit status 2
    */
    

     18.defer和匿名函数结合使用

    package main
    
    import "fmt"
    
    func main() {
    	a := 10
    	b := 20
    	defer func(a, b int) {
    		fmt.Printf("a = %d,b = %d
    ", a, b)
    	}(a, b) //代表调用此匿名函数,把参数传递过去,已经先传递参数,只是没有调用
    	a = 111
    	b = 222
    	fmt.Printf("外部:a = %d,b = %d
    ", a, b)
    	//输出结果为先打印外部: a=111,b=222之后打印的是a = 10,b = 20
    }
    
    func main01() {
    	a := 10
    	b := 20
    
    	defer func() {
    		fmt.Printf("a = %d,b = %d
    ", a, b)
    	}() //代表调用此匿名函数
    	a = 111
    	b = 222
    	fmt.Printf("外部:a = %d,b = %d
    ", a, b)
    	//输出结果为两个打印都为a = 111,b = 222
    }
    

     19.获取命令行参数

    package main
    
    import "fmt"
    import "os"
    
    func main() {
    	//接收用户传递的参数,都是以字符串方式传递到一个列表里面
    	list := os.Args
    
    	n := len(list)
    	fmt.Println("n = ", n)
    
    	//xxx.exe   a  b
    	for i := 0; i < n; i++ {
    		fmt.Printf("list[%d] = %s
    ", i, list[i])
    	}
    
    	//第二种方式
    	for _, data := range list {
    		fmt.Printf(" %s
    ", data)
    	}
    
    }
    

     20.局部变量

    package main
    
    import "fmt"
    
    func test() {
    	a := 10
    	fmt.Println("a = ", a)
    }
    
    func main() {
    	//定义在{}里面的变量就是局部变量,只能在{}里面有效
    	//执行到定义变量那句话,才开始分配空间,离开作用域
    	//作用域,变量起作用的范围
    	{
    		i := 10
    		fmt.Println("i = ", i)
    	}
    	if flag := 3; flag == 3 {
    		fmt.Println("flag = ", flag)
    	}
    }
    

     21.全局变量

    package main
    
    import "fmt"
    
    func test() {
    	fmt.Println("test a = ", a)
    }
    
    //定义在函数外部的变量是全局变量,全局变量在任何地方都能使用
    var a int
    
    func main() {
    	a = 10
    	fmt.Println("a = ", a)
    	test()
    }
    

     22.不同作用域同名变量

    package main
    
    import "fmt"
    
    var a byte //全局变量
    
    func main() {
    	var a int //局部变量
    
    	//1.不同作用域,允许定义同名变量
    	//2.使用变量的原则,就近原则
    	fmt.Printf("%T
    ", a) //int
    
    	{
    		var a float32
    		fmt.Printf("2: %T
    ", a) //float32
    	}
    
    	test()
    }
    
    func test() {
    	fmt.Printf("3: %T
    ", a) //unit8		就是byte类型
    
    }
    

     23.工作区

    Go代码必须放在工作区中。工作区其实就是一个对应于特定工程的目录,它应包含3个子目录:src目录、pkg目录和bin目录。
    src目录:用于以代码包的形式组织并保存Go源码文件。(比如:.go  .c  .h 等等)
    pkg目录:用于存放经由go install命令构建安装后的代码包(包含Go库源码文件)的 ".a"归档文件。
    bin目录:与pkg目录类似,在通过go install命令完成安装后,保存由Go命令源码文件生成的可执行文件。
    
    目录src用于包含所有的源代码,是Go命令行工具一个强制的规则,而pkg和bin则无需手动创建,如果必要Go命令行工具在构建过程中会自动创建这些目录。
    
    需要特别注意的是,只有当环境变量GOPATH中只包含一个工作区的目录路径时,go install命令才会把命令源码安装到当前工作区的bin目录下。
    若环境变量GOPATH中包含多个工作区的目录路径,像这样执行go install命令就会失败,此时必须设置环境变量GOBIN。
    
    GOPATH设置
    为了能够构建这个工程,需要先把所需工程的根目录加入到环境变量GOPATH中。否则,即使处于同一工作目录(工作区),代码之间也无法通过绝对代码包路径完成调用。
    

     24.导入包的常用方式

    package main
    
    /*
    //方式1
    import "fmt"
    import "os"
    
    //方式2 常用
    import (
    	"fmt"
    	"os"
    )
    
    //方式3 .操作
    import . "fmt" //调用函数,无需通过包名
    import . "os"
    
    //方式4	给包起别名
    import io "fmt"
    
    func main() {
    	io.Println("这是别名方式导入包")
    
    }
    
    //忽略此包
    import _ "fmt"		//该操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的init函数
    
    
    
    func main() {
    	fmt.Println("this is a test")
    	fmt.Println("os.Args = ", os.Args)
    	fmt.Println("this is a test")
    }
    */
    

     25.工程管理

    同级目录:
    1、分文件编程(多个源文件),必须放在src目录
    2、设置GOPATH环境变量
    3、同一个目录,包名必须一样
    4、go env查看go相关的环境路径
    5、同一个目录,调用别的文件的函数,直接调用即可,无需包名引用
    不同级目录:
    1、不同目录,包名不一样
    2、调用不同包里面的函数,格式:包名:函数名()
    3、调用别的包的函数,这个包函数名字如果是小写,无法让别人调用,要想别人调用,必须首字母大写
    
  • 相关阅读:
    Tcpdump抓包
    关于Adroid Bitmap OutOfMemoryError的问题解决
    java用substring函数截取string中一段字符串
    偶耶DIY布偶成都实体店开业
    瑞士Kardex(卡迪斯)自动化仓储货柜,Shuttle XP系列升降库驱动监控系统
    360顽固木马专杀工具 千万别用 会删除Oracle服务
    天上人和酒店管理系统(.net3.5 + sql2000 + linq to sql)
    [转]VC++中CListCtrl listcontrol用法技巧
    [转]孙鑫教程学习笔记
    [转]VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程
  • 原文地址:https://www.cnblogs.com/steven9898/p/11424267.html
Copyright © 2020-2023  润新知