首页 > 其他分享 >第四章(函数)

第四章(函数)

时间:2023-01-05 23:57:12浏览次数:40  
标签:函数 err int func println main 第四章

  • go函数特点
    • 无须前置声明
    • 不支持命名嵌套定义
    • 不支持同名函数重载
    • 不支持默认参数
    • 支持不定长变参
    • 支持多返回值
    • 支持命名返回值
    • 支持匿名函数和闭包
  • func只能判断其是否为nil,不支持其它比较操作
package main

func main() {
	println(a == nil) //false
	println(a == b) //invalid operation: a == b (func can only be compared to nil)
}

func a() {

}

func b() {

}
  • init()函数先于main函数执行,用于初始化

    • init函数没有输入参数、返回值
    • 每个包可以有多个init函数,多个init函数执行顺序go没有明确定义(注意不可依赖init函数执行顺序)
  • 不管是指针、引用类型、还是其它类型参数,都是值拷贝传递(pass-by-value)

  • 变参本质就是一个切片。只能接收一到多个同类型参数,且必须放在列表尾部。

func main() {

	test("abc", 1, 2, 3, 4)

}

func test(s string, a ...int) {
	fmt.Printf("%T,%v\n", a, a) //[]int,[1 2 3 4]
}
  • 将切片作为变参时,须进行展开操作。如果是数组,先将其转换为切片
func main() {
	a := [3]int{1, 2, 3}
	test(a[:]...) //先转换为切片,再展开

}
//可变参数
func test(a ...int) {
	fmt.Printf("%T,%v\n", a, a) //[]int,[1 2 3]
}
  • 命名返回值和参数一样,可当作函数局部变量使用,最有由return隐式返回
func main() {
	res, err := div(2, 0)
	if nil != err {
		println("err")
		os.Exit(-1)
	}
	println(res)
}

func div(x, y int) (z int, err error) {
	if 0 == y {
		err = errors.New("division by zero")
		return //隐式返回: 0,err
	}
	z = x / y
	return //隐式返回:z,nil
}

  • 闭包
    • 闭包是在其词法上下文中引用了自由变量的函数,或者说是函数和其引用的环境的组合体

    eg

        func main() {
        	f := test(0x100)
        	f()
    
        }
        func test(x int) func() {
        	println(&x) //0xc000055f68
        	return func() {
        		println(&x, x) //0xc000055f68 256
        	}
        }
    
    • 粗浅理解:闭包就是返回的匿名函数中引用了目标函数的变量,在main函数中执行时,可以正确读取变量的值。这种现象叫闭包
  • 闭包-“延迟求值”
func main() {
	for _, f := range test() {
		f()
	}
	//0xc000102000 2
	//0xc000102000 2
}
func test() []func() {
	var s []func()
	for i := 0; i < 2; i++ {
		s = append(s, func() {
			println(&i, i)
		})
	}
	return s
}

上面输出的结果是2,因为添加操作仅仅是将匿名函数放入切片,并未执行。因此,当main执行这些函数时,读取的是环境变量i最后一次循环的值2

如果想输出1,2那么给一个中间变量就oj8k了

  func main() {
  for _, f := range test() {
  	f()
  }
  //0xc000018050 0
  //0xc000018058 1
      }
      func test() []func() {
      	var s []func()
      	for i := 0; i < 2; i++ {
      		a := i
      		s = append(s, func() {
      			println(&a, a)
      		})
      	}
      	return s
      }


  • defer函数(延迟调用函数)向当前函数注册稍后执行的函数调用。

  • 错误处理

    eg

      func main() {
      z, err := div(5, 0)
      if err == errDivZero {
      	log.Fatalln(err) //2023/01/05 23:12:27 division by zero
      }
      println(z)
    }
    
    var errDivZero = errors.New("division by zero")
    
    func div(x, y int) (int, error) {
    	if 0 == y {
    
    		return 0, errDivZero
    	}
    	return x / y, nil
    }
    
    
  • panic,recover类型try/catch

    • 连续调用panic,仅最后一个会被recover捕获
        func main() {
        	defer func() {
        		if err := recover(); err != nil { //捕获错误
        			log.Fatalln(err)
        		}
        	}()
        	panic("i am panic")
        	println("here") //永远不会执行
        }
    
    • panic会立即中断当前函数流程,执行延迟调用。而在延迟调用函数中,recover可捕获并返回panic提交的错误对象
    • 无论是否recover,所有延迟调用都会被执行。panic要么被外层捕获,要么导致进程崩溃

标签:函数,err,int,func,println,main,第四章
From: https://www.cnblogs.com/badake/p/17028942.html

相关文章

  • 函数式组件与类组件
    类组件的优势:可以定义state,用以保存自己内部的变量;函数式组件不可以,每次调用后都会销毁函数内变量在函数式组件内部不使用副作用钩子定义的变量统称为局部变量,在函数每......
  • 在C#中获取如PHP函数time()一样的时间戳
    c#中没有象PHP一样的time()时间戳函数,但有DateTime.Now.Ticks用来计算时间差。此属性的值为自0001年1月1日午夜12:00以来所经过时间以100毫微秒为间隔表示时的数......
  • 关于C语言库函数qsort的学习
    #include<stdio.h>#include<stdlib.h>#include<string.h>structStu{charname[20];intage;};//voidqsort(void*base,//size_tnum,//size_twidth,//int(*cmp......
  • 欧拉函数与莫比乌斯函数的一些性质
    前置知识翡蜀定理与算数基本定理的证明积性函数若有一个数论函数\(f\)满足以下性质:\(\left(1\right)f\left(1\right)=1\)\(\left(2\right)\)若\(a,b\)互质,那么\(f\le......
  • 如何给所有的 await async 函数添加try/catch?
    如何给所有的awaitasync函数添加try/catch?做全局捕获异常。面试官:如何给所有的awaitasync函数添加try/catch?做全局捕获异常。我们可以使用window.addEventListene......
  • 函数式接口
    1.函数式接口只能含有1个方法的接口,入参可以有多个,出参可有可无定义接口@FunctionalInterfacepublicinterfaceReceiverGetter{ List<Receiver>apply(ResGroupr......
  • C++静态类成员变量和成员函数
    头文件calculateBufferSize.h#ifndefCALCULATE_BUFFER_SIZE#defineCALCULATE_BUFFER_SIZE#include<mutex>#include<memory>#include<iostream>#include<glm/g......
  • 函数
    函数"""先定义后调用(函数名+括号)函数名的命名规则跟变量名一样函数在定义的时候只检测函数体语法,不执行函数体代码函数名遇到括号会立即执行函数体代码"""#定......
  • Python 函数
    一.函数的初识函数:以功能(完成一件事)为导向,登录,注册,len一个函数就是一个功能。随调随用函数的优势1.减少了代码的重复性。2.增强了代码的可读性 二.函数的结构和调用......
  • C#调用VC的DLL的接口函数参数类型转换一览表
    handle---------IntPtrhwnd-----------IntPtrchar*----------stringint*-----------refintint&-----------refintvoid*----------IntPtrunsignedchar*-----refbyt......