[go]函数

摘要:
返回值必须有一个显式返回语句-不明确的functest{ifx>0{return1}elseifx<0{return 0}}-多个返回值括在括号中funcdiv{ify==0{turn0,errors。New}-命名的多个返回函数funcparding{}隐式返回funcdiv{ify==0{err=errors。Newreturn}z=x/yrturn//等同于“returnz,err”}-要命名所有匿名函数,可以在函数内部定义没有名称符号的函数。匿名函数可以作为参数和返回值直接调用并保存到变量中-直接执行func{println}-存储为变量s:=“hello”fn:=func{println}fn-作为参数functest{f()}funcmin(){test(func(){println(“hello,world!”)})}-作为返回值functest()funcint{returnfuncint{returnx+y}funmain(){add:=test()println}–匿名结构类型calcstruct{//定义结构类型mulfunct//函数类型字段}-作为chan元素x:=calc{mul:func(x,yi

init执行顺序

对同一个 go 文件的 init( ) 调用顺序是从上到下的
对同一个 package 中的不同文件,将文件名按字符串进行“从小到大”排序,之后顺序调用各文件中的init()函数
对于不同的 package,如果不相互依赖的话,按照 main 包中 import 的顺序调用其包中的 init() 函数
如果 package 存在依赖,调用顺序为最后被依赖的最先被初始化,例如:导入顺序 main –> A –> B –> C,则初始化顺序为 C –> B –> A –> main,一次执行对应的 init 方法

[go]函数第1张

main函数

//main不支持参数,传参使用os.Args
func main() {
	fmt.Println(os.Args)
}

//$: go run main.go 1 2 3
//[/var/folders/4g/nfky9hks3j39qhvz741tmcn40000gn/T/go-build150967295/b001/exe/main 1 2 3]
//main函数不支持返回值

func main() int{
	return 10
}
//$: go run main.go
//# command-line-arguments
//./main.go:3:6: func main must have no arguments and no return values
//main函数返回状态值的方法: os.Exit
func main() {
	fmt.Println("hello")
	os.Exit(-1)
}
//$: go run main.go
//hello
//exit status 255

定义

- 特点
函数是结构化编程的最小模块单元.
将复杂的算法过程分解为若干较小任务, 隐藏相关细节. 使得程序结构更加清晰.便于维护.

普通函数则专注于算法流程,通过接收参数来完成特定逻辑运算,并返回最终结果

支持前置声明
    func main() {
        test()
    }

    func test() {
        println("100")
    }

不支持同名重载
    func test() {
        println("100")
    }

    func test() {
        println("200")
    }

不支持命名嵌套定义
    func main() {
        func test() {
            println("200")
        }
    }
不支持默认参数
支持不定长边参
    func test(a int, n ...int) {
        fmt.Println(a, n) //10 [1 2 3]
    }

    func main() {
        arr := []int{1, 2, 3}
        test(10, arr...)
    }
支持多返回值
支持命名返回值
支持匿名函数和闭包


- 闭包
func test() func() {
	age := 0
	return func() {
		age++
		println(age)
	}
}

func main() {
	f := test()
	f()
	f()
	f()

}


- 延迟调用
func test(fn func()) func() {
	time := 0
	return func() {
		time++
		if time > 2 {
			fn()
		}
	}

}

func main() {
	run := test(func() {
		println("hello world")
	})
	run()
	run()
	run() //在执行第三次时才触发
}

只能和nil比较
func(){} == nil

参数

- 参数
不支持可选,不支持命名实参

按顺序传参数
func test(x, y int, s string, _ bool) *int {
	return nil
}

func main() {
	test(1, 2, "", false) 
}

形参类似是局部变量, 重复声明会出错
    func test(x, y int) {
        x := 100
        var y int
    }


- 无论是哪种类型都传参都是值传递,无非是拷贝的是指(尽管他们指向的同一个对象)针还是值.
func test(x *int) {
	fmt.Printf("%p
", &x)
}

func main() {
	a := 10
	fmt.Printf("%p
", &a)
	test(&a)
}
//0xc0000160c0
//0xc000006030


- 参数过多可以放到一个符合类型中, 变向的实现可选参数和命名实参的功能
type serverOption struct{ 
   address string
   port  int
   path  string
   timeout time.Duration
   log    *log.Logger
} 
  
func newOption() *serverOption{ 
   return&serverOption{             // 默认参数 
       address: "0.0.0.0", 
       port:   8080, 
       path:    "/var/test", 
       timeout:time.Second*5, 
       log:    nil, 
    } 
} 
  
func server(option*serverOption) {} 
  
func main() { 
   opt:=newOption() 
   opt.port=8085         // 命名参数设置 
  
   server(opt) 
}



- 可变参数(本质是一个切片,只能放在尾部)
func test(s string,a...int) { 
   fmt.Printf("%T, %v
",a,a)       // 显示类型和值 
} 
  
func main() { 
   test("abc",1,2,3,4) 
}

- 切片作为变参时,必须进行展开操作, 如果是数组,则将其转换为切片
func test(a...int) { 
   fmt.Println(a) 
} 
  
func main() { 
   a:= [3]int{10,20,30} 
   test(a[:]...)            // 转换为slice后展开 
}

既然变参是切片,那么参数复制的仅是切片自身,并不包括底层数组,也因此可修改原数据。


返回值

必须要有明确的return语句
- 不明确
func test(x int) int {
	if x > 0 {
		return 1
	} else if x < 0 {
		return 0
	}
}

- 多返回值用括号括起来
func div(x,y int) (int,error) { 
   if y==0{ 
       return 0,errors.New("division by zero") 
    } 

- 命名多返回值
func paging(sql string,index int) (count int,pages int,err error) { 
}


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


- 要命名都命名

匿名函数

没有定义名字符号的函数
可以在函数内部定义匿名函数

可以被直接调用
可保存到变量
可以作为参数和返回值


- 直接执行
	func(s string){
		println(s)
	}("hello mm")


- 存储为变量
	s := "hello"
	fn := func(s string) {
		println(s)
	}
	fn(s)

- 作为参数
func test(f func()) { 
   f() 
} 
  
func main() { 
   test(func() { 
       println("hello,world!") 
    }) 
}

- 作为返回值
func test()func(int,int)int{ 
   return func(x,y int)int{ 
       return x+y
    } 
} 
  
func main() { 
   add:=test() 
   println(add(1,2)) 
}


- 匿名结构体类型
   type calc struct{                // 定义结构体类型 
       mul func(x,y int)int         // 函数类型字段 
    } 
  
- 作为chan元素
   x:=calc{ 
       mul:func(x,y int)int{ 
           return x*y
        }, 
    } 

    c:=make(chan func(int,int)int,2) 


- 闭包的延迟特性
函数和其引用环境的组合

func test(x int)func() { 
   return func() { 
       println(x) 
    } 
} 
  
func main() { 
   f:=test(123) 
   f() 
}


延迟调用

defer想当前函数注册时候执行的函数调用
因为他直到当前函数执行结束前才执行
常用语资源释放,解除锁定,错误处理等操作


func main() { 
   f,err:=os.Open("./main.go") 
   if err!=nil{ 
       log.Fatalln(err) 
    } 
  
   defer f.Close()          // 仅注册,直到main退出前才执行 
  
    ...do something... 
}


延迟调用注册的是调用,必须提供执行所需的参数
参数值是在注册时候, 被赋值缓存起来, 如对状态敏感, 可改用指针或闭包
func main() {
	x := 1
	defer println(x) //注册时拷贝一份当前变量值
	x = 100
	println(x)
}
// 100 1


多个延迟注册按FILO次序执行。
func main() { 
   defer println("a") 
   defer println("b") 
}



免责声明:文章转载自《[go]函数》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇sap ABAP关于Data Reference的使用FIELDSYMBOLS手工注入下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

gcc/g++编译

1. gcc/g++在执行编译工作的时候,总共需要4步 (1).预处理,生成.i的文件[预处理器cpp] (2).汇编,将预处理后的文件转换成汇编语言,生成文件.s[编译器egcs] (3).编译,将汇编语言文件编译为目标代码(机器代码)生成.o的文件[汇编器as] (4).链接,将目标代码,生成可执行程序[链接器ld] [参数详解]   -x lang...

Debian 7 Wheezy 配置: 中文字体美化

参考的是这篇文章 http://blog.csdn.net/qq280948982/article/details/6782603 首先通过sudo apt-get install 直接安装 ttf-wqy-zenhei. 另外我还安装了 xfonts-wqy.这两个字体安装完后, 不需要额外设置, Chrome的中文字体方块乱码问题就自动修复了, Ice...

go语言 robfig/cron包 实现定时 调用

package main import ( "github.com/robfig/cron" "time" "fmt" "os" log "github.com/cihub/seelog" ) var ( ttt int ) const ( logFilePath = "hard/log/test/t...

bert训练代码

from torch.optim import Adam from torch.utils.data import DataLoader from dataset.wiki_dataset import BERTDataset from models.bert_model import * import tqdm import pandas as pd...

在workbench中导入.sql文件!(导入数据库文件)

第一步,登陆mysql workbench 第二步,打开自己的数据 ,此处默认(root) 打开数据库后页面 : 第三步,新建一个schema ,随便给个名字,这里起名为test : 可以看到test 内的table ,views,routines,等选项都是没有任何内容的。 第四步 ,在file 下打开你需要导入的.sql 文件。...

SHELL脚本编程循环篇-while循环

              SHELL脚本编程循环篇-while循环                                           作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 一.while循环的语法格式 while CONDITION; do   循环体 done 以上参数关键点说明:   C...