zoukankan      html  css  js  c++  java
  • 【Go语言学习笔记】Go的函数

    函数还是这几块:

    • 参数
    • 返回值
    • 作用域
    • 执行顺序

    参数和返回值

    func FuncName(/*参数列表*/) (o1 type1, o2 type2/*返回类型*/) {
        //函数体
     
        return v1, v2 //返回多个值
    }
    

    和C差不多,但是有点不一样的是:

    • 函数名首字母小写即为private,大写即为public。(即跨文件调用需要大写)
    • 可以有多个返回值,而且返回值可以预订变量名。
    • 可以有不定参数
    package main
    
    import "fmt"
    
    func Test() { //无参无返回值函数定义
    	fmt.Println("this is a test func")
    }
    
    //有参无返回值
    func Test01(v1 int, v2 int) { //方式1
    	fmt.Printf("v1 = %d, v2 = %d
    ", v1, v2)
    }
    
    func Test02(v1, v2 int) { //方式2, v1, v2都是int类型
    	fmt.Printf("v1 = %d, v2 = %d
    ", v1, v2)
    }
    
    //不定参数
    //形如...type格式的类型只能作为函数的参数类型存在,并且必须是最后一个参数
    func Test03(args ...int) {
    	for _, n := range args { //遍历参数列表
    		fmt.Println(n)
    	}
    }
    
    //不定参数的传递
    func Test04(args ...int) {
    	Test03(args...)     //按原样传递, Test()的参数原封不动传递给MyFunc01
    	Test03(args[1:]...) //Test()参数列表中,第1个参数及以后的参数传递给MyFunc02
    }
    
    //不定参数且类型不一样
    func MyPrintf(args ...interface{}) {
    	for _, arg := range args {
    		switch arg.(type) {
    		case int:
    			fmt.Println(arg, "is an int value.")
    		case string:
    			fmt.Println(arg, "is a string value.")
    		case int64:
    			fmt.Println(arg, "is an int64 value.")
    		default:
    			fmt.Println(arg, "is an unknown type.")
    		}
    	}
    }
    
    func main() {
    	Test() //无参无返回值函数调用
    
    	Test01(10, 20) //函数调用
    	Test02(11, 22) //函数调用
    
    	Test03(1)
    	Test03(1, 2, 3)
    
    	Test04(4, 5, 6)
    
    	var v1 int = 1
    	var v2 int64 = 234
    	var v3 string = "hello"
    	var v4 float32 = 1.234
    	MyPrintf(v1, v2, v3, v4)
    }
    
    
    package main
    
    import "fmt"
    
    func test01() int { //方式1
    	return 250
    }
    
    //官方建议:最好命名返回值,因为不命名返回值,虽然使得代码更加简洁了,但是会造成生成的文档可读性差
    func test02() (value int) { //方式2, 给返回值命名
    	value = 250
    	return value
    }
    
    func test03() (value int) { //方式3, 给返回值命名
    	value = 250
    	return
    }
    
    //多个返回值
    //求2个数的最小值和最大值
    func MinAndMax(num1 int, num2 int) (min int, max int) {
    	if num1 > num2 { //如果num1 大于 num2
    		min = num2
    		max = num1
    	} else {
    		max = num2
    		min = num1
    	}
    
    	return
    }
    
    func main() {
    	v1 := test01() //函数调用
    	v2 := test02() //函数调用
    	v3 := test03() //函数调用
    	fmt.Printf("v1 = %d, v2 = %d, v3 = %d
    ", v1, v2, v3)
    
    	min, max := MinAndMax(33, 22)
    	fmt.Printf("min = %d, max = %d
    ", min, max) //min = 22, max = 33
    }
    
    

    作用域

    作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。

    函数内定义的变量称为局部变量。
    函数外定义的变量称为全局变量。

    在不同作用域可以声明同名的变量,其访问原则为:在同一个作用域内,就近原则访问最近的变量,如果此作用域没有此变量声明,则访问全局变量,如果全局变量也没有,则报错。

    局部变量

    在函数体内声明的变量、参数和返回值变量就是局部变量,它们的作用域只在函数体内:

    func test(a, b int) {
        var c int
        a, b, c = 1, 2, 3
        fmt.Printf("a = %d, b = %d, c = %d
    ", a, b, c)
    }
     
    func main() {
        //a, b, c = 1, 2, 3 //err, a, b, c不属于此作用域
        {
            var i int
            i = 10
            fmt.Printf("i = %d
    ", i)
        }
     
        //i = 20 //err, i不属于此作用域
     
        if a := 3; a == 3 {
            fmt.Println("a = ", a)
        }
        //a = 4 //err,a只能if内部使用
    }
    

    全局变量

    在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用。

    var a int //全局变量的声明
     
    func test() {
        fmt.Printf("test a = %d
    ", a)
    }
     
    func main() {
        a = 10
        fmt.Printf("main a = %d
    ", a) //main a = 10
     
        test() //test a = 10
    }
    

    不同作用域同名变量

    在不同作用域可以声明同名的变量,其访问原则为:在同一个作用域内,就近原则访问最近的变量,如果此作用域没有此变量声明,则访问全局变量,如果全局变量也没有,则报错。

    var a int //全局变量的声明
     
    func test01(a float32) {
        fmt.Printf("a type = %T
    ", a) //a type = float32
    }
     
    func main() {
        fmt.Printf("a type = %T
    ", a) //a type = int, 说明使用全局变量的a
     
        var a uint8 //局部变量声明
     
        {
            var a float64                  //局部变量声明
            fmt.Printf("a type = %T
    ", a) //a type = float64
        }
     
        fmt.Printf("a type = %T
    ", a) //a type = uint8
     
        test01(3.14)
        test02()
    }
     
    func test02() {
        fmt.Printf("a type = %T
    ", a) //a type = int
    }
    

    执行顺序

    和C一样,顺序执行,有递归还是按栈的顺序。

    唯一的区别,在于defer,单独开一篇写。

  • 相关阅读:
    java编译错误No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A(
    java 2中创建线程方法
    动态规划基本思想
    关于eclipse编译一个工程多个main函数
    java Gui初识
    Eclipse中java项目的打包
    java 播放声音
    把资源文件夹导入到eclipse中
    Java建立JProgressBar
    How to grant permissions to a custom assembly that is referenced in a report in Reporting Services
  • 原文地址:https://www.cnblogs.com/HappyTeemo/p/15457348.html
Copyright © 2011-2022 走看看