/*
函数的定义格式
func 函数名(形参列表)(返回值列表){
}
*/
package main
import (
"fmt"
"math"
)
//函数一:
func Add(a, b int)int{
return a + b
}
//函数二:
func Sub(a, b int)int{
return a - b
}
//函数三:
func hhh(a, b float64)float64{
return math.Sqrt(a*a + b*b)
}
func main() {
c := Add(10, 11)
d := Sub(23, 30)
e := hhh(40,30)
fmt.Println("c=",c)
fmt.Println("d=",d)
fmt.Println("e=",e)
}
若返回值是同一种类型,则用括号将多个返回值类型括起来,用逗号分隔每个返回值类型
/*
函数的定义格式
func 函数名(形参列表)(返回值列表){
}
*/
package main
import (
"fmt"
)
func hhh()(int, int){
a := 100
var b int=300
return a, b
}
func main() {
c, d := hhh()
fmt.Println("c=",c)
fmt.Println("d=",d)
}
Go语言支持对返回值进行命名,这样返回值就和参数一样有参数变量名和类型;命名的返回值变量的默认值为类型的默认值,即数值为0,字符串为空字符串,布尔值为false,指针为nil等。
package main
import (
"fmt"
)
func hhh()(a bool, b int){
a = true
b = 300
return
}
func main() {
c, d := hhh()
fmt.Println("c=",c)
fmt.Println("d=",d)
}
package main
import "fmt"
//可变参数列表 ...interface{}
func hhh(args ...interface{})(){
for _,arg := range args{
switch arg.(type){
case int:
fmt.Println(arg,"is type of int")
case float64:
fmt.Println(arg,"is type of float64")
case bool:
fmt.Println(arg, "is type of bool")
case string:
fmt.Println(arg,"is type of string")
default:
fmt.Println(arg,"is the unknown type")
}
}
}
func main() {
var i int=100
var f float64=3.1415
var b bool=true
var s string="hello world"
var iptr *int=&i
hhh(i, f, b, s, iptr)
}
结果:package main
import (
"fmt"
)
func hhh(a bool, b int)(){
fmt.Println("a=",a)
fmt.Println("b=",b)
}
func main() {
var fnc func(bool, int)
fnc = hhh
fnc(true, 10000) //实际调用的是hhh函数
}
结果/*
匿名函数语法:
func(参数列表)(返回值列表){
函数体
}
*/
package main
import "fmt"
func main() {
//将匿名函数保存到变量res中
res := func(a, b int){
c := a + b
fmt.Println("c = ", c)
}
//使用res()调用
res(100,200)
}
结果:package main
import "fmt"
func visit(slc []int, f func(int)){
for _,v := range slc{
f(v)
}
}
func main() {
//使用匿名函数遍历打印切片,将匿名函数作为参数传入函数visit中
visit([]int{1,2,3,4,5,6,7,8,9,10}, func(v int){
fmt.Println(v)
})
}
闭包:引用了外部变量的匿名函数。是指有权访问另一个函数作用域中的变量的函数。
Go中闭包是引用了自由变量的函数,被引用的自由变量和函数一同存在,即使已经离开了自由变量的环境也不会被释放或者删除,在闭包中可继续使用这个自由变量,因此,闭包里作用域返回的局部变量不会被立刻销毁回收,但过度使用闭包可能会占用更多内存,导致性能下降。简单来说:
闭包 = 函数 + 引用环境
闭包的本质是函数,但是这个函数会用到函数外的变量,它们共同组成的整体即闭包。如下面的str和匿名函数共同组成的整体叫做闭包。
package main
import "fmt"
func main(){
str := "hello world"
fmt.Println("变成闭包前:")
fmt.Println(str)
//匿名函数中访问str
foo := func(){
str = "hello sheena!!!!"
}
//调用匿名函数
foo()
fmt.Println("变成闭包后:")
//闭包str拥有了记忆
fmt.Println(str)
}
package main
import (
"fmt"
)
//定义接口
type Sheena interface {
//接口中的方法
MyPrint(interface{})
}
//定义接口体
type MyStruct struct {
}
//结构体变量实现接口方法
func (ms *MyStruct)MyPrint(pi interface{}){
fmt.Println("from my struct" , pi)
}
//函数定义为类型
type FuncCall func(interface{})
//函数边领实现接口方法
func (fc FuncCall)MyPrint(fi interface{}){
//调用f函数本体
fc(fi)
}
func main(){
//声明接口变量
var sea Sheena
//实例化结构体
st := new(MyStruct)
//将实例化的结构体赋值到接口
sea = st
//使用接口调用实例化结构体方法Struct.MyPrint
sea.MyPrint(33333)
//将匿名函数转为FuncCall类型,再赋值给接口
sea = FuncCall(func(v interface{}){
fmt.Println("from function aaa", v)
})
//使用接口调用FuncCall,MyPrint,内部会调用函数本体即匿名函数
sea.MyPrint(1111)
}
结果:package main
import "fmt"
func main(){
fmt.Println("::::defer begin::::")
defer fmt.Println("a") //将defer放入延迟调用栈
defer fmt.Println("b")
defer fmt.Println("c")
defer fmt.Println("d")
defer fmt.Println("e") //最后一个放入,位于栈顶,最先调用
fmt.Println("::::defer end::::")
}
结果:package main
import (
"fmt"
"sync"
)
var vslueMutex sync.Mutex
func hhhh(key string)int{
mymp := map[string]int{"aaaa":111}
vslueMutex.Lock()
//defer后面的语句不会马上调用,而是延迟到函数结束时调用
defer vslueMutex.Unlock()
return mymp[key]
}
func main(){
fmt.Println(hhhh("aaaa"))
}
详情请看博客Go语言之defer(原理、常见的坑)
type error interface{
Error() string
}
package main
import (
"errors"
"fmt"
)
var myError = errors.New("this is an error!!!!!!!")
func fc(i,j int)(int, error){
if(i == 0){
return 0, myError
}
return j, nil
}
func main(){
fmt.Println(fc(1,3))
fmt.Println(fc(0,1))
}
package main
import "fmt"
func main(){
fmt.Println("helllo world!!!!!!")
panic("出错啦!!crash啦!!")
fmt.Println("!!!!!!helllo world")
}
package main
import "fmt"
func main(){
a := []int{0,1,2,3,4,5,6,7,8,9}
i:=11
for i=0;i<len(a);i++{
fmt.Printf(" %d ",a[i])
}
fmt.Println()
if i>=len(a){
panic("数组越界啦!!!crash")
}
}
package main
import "fmt"
func main(){
a := []int{0,1,2,3,4,5,6,7,8,9}
i:=11
for i=0;i<len(a);i++{
fmt.Printf(" %d ",a[i])
}
fmt.Println()
defer fmt.Println("defer要执行的语句11111")
defer fmt.Println("defer要执行的语句22222")
if i>=len(a){
panic("数组越界啦!!!crash")
}
defer fmt.Println("defer要执行的语句33333不会执行")
}
package main
import (
"fmt"
"runtime"
)
func main(){
a := []int{0,1,2,3,4,5,6,7,8,9}
i:=11
for i=0;i<len(a);i++{
fmt.Printf(" %d ",a[i])
}
fmt.Println()
defer fmt.Println("defer要执行的语句11111")
defer fmt.Println("defer要执行的语句22222")
defer func(){
err := recover()
switch err.(type) {
case runtime.Error://运行时错误
fmt.Println("运行时发生错误:::error:", err)
default:
fmt.Println("unknown error:::error:", err)
}
}()
if i>=len(a){
panic("数组越界啦!!!crash")
}
defer fmt.Println("defer要执行的语句33333不会执行")
}
package main
import (
"fmt"
"time"
)
func fct(arr []int)(){
sum := 0
for i:=0; i<len(arr); i++{
sum++
}
fmt.Println("结果:", sum)
}
func main(){
a := []int{0,1,2,3,4,5,6,7,8,9,10}
start := time.Now()//获取当前时间
fct(a)
res := time.Since(start)//计算出到当前时间到start的时间戳
fmt.Println("该函数执行完成的耗时是:", res)
}