zoukankan      html  css  js  c++  java
  • go 语言 函数

    1.函数声明:

    func function_name (parameter list) (return_types) {

      函数体

    }

    • func:函数由 func 开始声明
    • function_name:函数名称,函数名和参数列表一起构成了函数签名。
    • parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
    • return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
    • 函数体:函数定义的代码集合

    下面的更进一步的说明:(跟上面是一样的,都是函数的声明)

    func funcName(形参1 type[, 形参2 type...]) [([[返回变量1] type[, [返回变量2] type...]])] {
        [return [返回变量1[, 返回变量2...]]]
      }
      a. 如果形参类型都一样,可以这样写: 形参1, 形参2 type, 同时返回变量也一样
      b. 如果只有一个返回值或者无返回值, 可以去掉对应的()
      c. 如果返回有返回值,该函数中最外层要有return语句
      d. 返回语句(), 返回变量名可以省略
      e. []表示可省略
      f. 不支持默认参数

    2. 函数的特点:

    1)函数即是变量

    x:=1

    y:=x

    上面的变量的赋值,即函数也可以像变量一样赋值

    package main
    
    import(
    	"fmt"
    )
    func Add(a,b int)int{
    	
    	return a + b
    }
    func main(){
    	var c func(int,int) int
    	c =Add
    	fmt.Printf("%p %T %p %T
    ",c,c,Add,Add)//0x497fe0 func(int, int) int 0x497fe0 func(int, int) int   c和Add的内存地址是同一个,
    	//说明c和Add使用同一块内存地址里保存的内容。c = Add只是又给内存的一块地址增加了一个名字。
    	sum:=c(10,20)
    	fmt.Printf("sum的值是:%d
    ",sum)//30
    	sum=Add(10,20)
    	fmt.Printf("sum的值是:%d
    ",sum)//30  c 和Add是等效的
    }
    

      2)回调函数 

    回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

    函数指针是指向函数的指针变量。因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。函数指针有两个用途:调用函数和做函数的参数

    type callback func(int,int)int // 定义一个带有两个int类型的参数,一个返回值 类型 为int类型的函数叫callback
    
    func Add(a,b int){ //定义回调函数
    	
    	return a + b
    }
    func callbacktest(a, b int,callback callback) int{ //定义一个函数,把callback类型的函数当作参数传递给这个函数
    	return callback(a,b)  //返回callback类型函数的结果,相当于调用回调函数
    }
    func main(){
        fmt.Println(callbacktest(20,30,Add)) //50  触发调用
    }
    

      3)函数参数传递方式

               1.值传递

          2.引用传递

                     ⽆论是值传递,还是引⽤传递,传递给函数的都是变量的副本,不过,值传递是值的拷⻉。引⽤传递是地址的拷⻉,⼀般来说,地址拷⻉更为⾼效。⽽值拷⻉取决于拷⻉的对象⼤⼩,对象越⼤,则性能

                     越低。

                   mapslicechan、指针、 interface默认以引⽤的⽅式传递

        

    func Change(a int){
    	a = 200
    }
    func Change1(a *int){
    	*a = 200
    }
    func ChangeSlice(b []int){
    	b[0] = 100
    	b[1] = 200
    	b[5] = 500
    }
    func TestValuePass(){
    	a:=100
    	Change(a)
    	fmt.Printf("a的值是:%d
    ",a) //100  a没有被改变,值传递
    	Change1(&a)
    	fmt.Printf("a的值是:%d
    ",a) //200  指针传递
    	var b []int
    	b = make([]int,20,30)
    	ChangeSlice(b)   //切片传递
    	fmt.Printf("%#v
    ",b)//[]int{100, 200, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    
    	
    }
    

      4)命名返回值

            

    func Minus(a,b int)(c int){
    	c = a+b
    	return                   //省略了返回值的名字
    }
    func cacl(a,b int)(sum,avg int){
    	sum = a+b
    	avg = (a+b)/2
    	return          省略了返回值的名字
    }
    func TestNamedRe(){
    	fmt.Printf("%d
    ",Minus(1000,2000)) //3000
    	sum,avg := cacl(1000,2000)
    	fmt.Printf("sum 的值=%d avg的值=%d",sum,avg) //3000  1500
    }
    

      5)_标识符,⽤来忽略返回值:

    func cacl(a,b int)(sum,avg int){
    	sum = a+b
    	avg = (a+b)/2
    	return
    }
    func TestNamedRe(){
    	sum,_ := cacl(1000,2000)
    	fmt.Printf("sum 的值=%d",sum) //3000
    }
    

      6)可变参数

    func add(arg…int) int {
    }                                                           0个或者多个参数 

    func add(a int,arg…int) int {                1个或者多个参数
    }

    func add(a int,b int,arg…int) int {         2个或者多个参数
    }

    arg 可以被任意合法的标识符替代

    其中arg是⼀个slice,我们可以通过arg[index]依次访问所有参数
    通过len(arg)来判断传递参数的个数

    func indefinite(args...int){
    	fmt.Println(args)        // 打印出每个参数 100 200     
    	for _,v:= range(args){
    		fmt.Printf("%d
    ",v)  /100  200
    	}
    	var sum int
    	for i:=0;i<len(args);i++{      //len(args) 求出参数的长度
    		sum = sum + args[i]     //args[i]     求出每个参数的值
    	}
    	fmt.Printf("%d
    ",sum)  //300
    }
    func testindefinite(){
    	a := 100
    	b := 200
    	indefinite(a,b)   
    }
    

      同样是上面的indenifite(args …int)函数为例,在参数赋值时可以不用用一个一个的赋值,可以直接传递一个数组或者切片,特别注意的是在参数后加上“…”即可。

    func indefinite(aaa...int){
    	fmt.Println(aaa)
    	for _,v:= range(aaa){
    		fmt.Printf("%d
    ",v)
    	}
    	var sum int
    	for i:=0;i<len(aaa);i++{
    		sum = sum + aaa[i]
    	}
    	fmt.Printf("%d
    ",sum)
    }
    func testindefinite(){
    	arr := []int{100, 200, 300}
    	indefinite(arr...)
    	indefinite(arr[:2]...)	
    	// a := 100
    	// b := 200
    	// indefinite(a,b)   // 100 200
    }
    //输出结果
    [100 200 300]
    100
    200
    300
    600
    [100 200]
    100
    200
    300
    

     

    3.匿名函数

    匿名函数是指不需要定义函数名的一种函数实现方式。

    在Go里面,函数可以像普通变量一样被传递或使用,Go语言支持随时在代码里定义匿名函数。 
    匿名函数由一个不带函数名的函数声明和函数体组成。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。 
    直接看一个例子:

    func main(){
    getSqrt := func(a float64) float64 {        //匿名函数需要赋值给一个变量来调用,需要有一个名字,否则无法调用。就跟调用变量一样,也是需要一个名字的。
    		return math.Sqrt(a)
    	}
    	fmt.Printf("%f
    ",getSqrt(8))
    	fmt.Printf("%f
    ",getSqrt(16))
    }
    //运行结果
    2.828427
    4.000000
    

     4.递归函数

    ⼀个函数调⽤⾃⼰,就叫做递归。

    递归的设计原则
    1)⼀个⼤的问题能够分解成相似的⼩问题
    2)定义好出⼝条件

    利用递归函数可以很方便的求解问题,例如阶乘、斐波那契数列

    func factorial(n int)int{
    	if n ==1 {
    		return 1
    	}else{
    		return factorial(n-1)*n
    	}
    }
    func testfac(){
    	n:=factorial(5)
    	fmt.Printf("%d",n)  // 120
    
    }//阶乘
    

      

    func fibonacii(n int)int{
    	if n<=1 {
    		return 1
    	}
    	return fibonacii(n-1) + fibonacii(n-2)
    }
    func testfibonacii(){
    	for i:=0;i<10;i++{
    		n:=fibonacii(i)
    		fmt.Printf("%d,",n) //1,1,2,3,5,8,13,21,34,55,
    		
    	}
    }  //斐波那契
    

      



                       

  • 相关阅读:
    nginx 配置 开发
    导入excel 数据到mysql出现的时间格式
    gradle 集成到myeclipse
    多线程同步和异步的方式
    谈一下spring 的理解
    java 中的反射
    Sublime Text 下配置python
    Python元组的简单介绍
    Python中strip()函数
    Python中的repr()函数
  • 原文地址:https://www.cnblogs.com/wanghaijun999/p/8184576.html
Copyright © 2011-2022 走看看