Go语言 函数,工程管理
Go语言 函数,工程管理
1、无参无返回值函数的使用
package main import "fmt" func main() { // 无参无返回值函数的调用:函数名() func1() } // 无参无返回值函数的定义 func func1() { str1 := "mysql -uroot -p123456 -S /data/3306/mysql.socket" fmt.Println("mysql数据库本地登录命令是#", str1) }
2、普通参数列表
package main import "fmt" // 有参无返回值函数的定义,普通参数列表 // 定义函数时,在函数名后面()定义的参数叫形参 // 参数传递,只能由实参传递传递给形参,不能反过来,单向传递 func func1(a int) { fmt.Println("a =", a) } func func2(a int, b int) { fmt.Printf("a = %d, b = %d\n", a, b) } func func3(a, b int) { fmt.Printf("a = %d, b = %d\n", a, b) } func func4(a int, b string, c float64) { } func func5(a, b string, c float64, d, e int) { } func func6(a string, b string, c float64, d int, e int) { } func main() { // 有参无返回值函数调用:函数名(所需参数) // 调用函数传递的参数叫实参 func1(666) func2(666, 777) }
3、不定参数类型 args ...type
package main import "fmt" func func1(a int, b int) { // 固定参数 fmt.Printf("a = %d, b = %d\n", a, b) } // ...int类型这样的类型,...type不定参数类型 // 注意:不定参数,一定只能放在形参中的最后一个参数 func func2(args ...int) { // 传递的实参可以是0个或多个 fmt.Println("len(args) =", len(args)) // 获取用户传递参数的个数 for i := 0; i < len(args); i++ { fmt.Printf("args[%d] = %d\n", i, args[i]) } } // 返回2个值,第一个是下标,第二个是下标所对应的数 func func3(args ...int) { for i, data := range args { fmt.Printf("args[%d] = %d\n", i, data) } } // 固定参数一定要传参,不定参数根据需求传参 func func4(a int, args ...int) { fmt.Println("a =", a) for i, data := range args { fmt.Printf("args[%d] = %d\n", i, data) } } // 注意:不定参数一定要放在形参中的最后一个参数位置。 // func func5(args ...int, a int) { // } func main() { func1(666, 777) fmt.Println("--------------------------") func2(111, 222, 333, 444, 555) fmt.Println("--------------------------") func3(10, 11, 12, 13, 14, 15) fmt.Println("--------------------------") func4(9, 10, 11, 12, 13, 14, 15) fmt.Println("--------------------------") func4(9) }
4、不定参数传参
package main import "fmt" func func1(tmp ...int) { for _, data := range tmp { fmt.Println("data =", data) } } func func2(tmp ...int) { for _, data := range tmp { fmt.Println("data =", data) } } func test(args ...int) { // 全部元素传递给func1 // func1(args...) // 只想把后2个参数传递给两外一个函数使用 func2(args[:2]...) // args[0]~args[2] 不包括数字args[2],传递过去 fmt.Println("-----------------") func2(args[2:]...) // 从args[2]开始 包括本身,把后面所有元素传递过去 } func main() { test(1, 2, 3, 4) }
5、一个返回值
package main import "fmt" // 无参有返回值:只有一个返回值 // 有返回值的函数需要通过return中断函数,通过return返回 func func1() int { return 666 } // 给返回值起一个变量名,Go推荐写法 func func2() (result int) { return 666 } // 给返回值起一个变量名,Go推荐写法 // 常用写法 func func3() (result int) { result = 666 return result } func main() { // 无参有返回值函数调用 var a int a = func1() fmt.Println("a =", a) b := func2() fmt.Println("b =", b) c := func3() fmt.Println("c =", c) }
6、有多个返回值
package main import "fmt" // 有多个返回值 func func1() (int, int, int) { return 3306, 3307, 3308 } // Go官方推荐写法 func func2() (a int, b int, c int) { a, b, c = 3306, 3307, 3308 return } func func3() (a, b, c int) { a, b, c = 3306, 3307, 3308 return } func main() { // 函数调用 a, b, c := func3() fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c) }
7、有参有返回值
package main import "fmt" func func1(a, b int) (max, min int) { if a > b { max = a min = b } else { max = b min = a } return // 有返回值的函数,必须通过return返回 } func main() { max, min := func1(10, 20) fmt.Printf("max = %d, min = %d\n", max, min) }
8、普通函数的调用流程
package main import "fmt" func funcc(c int) { fmt.Println("c =", c) } func funcb(b int) { funcc(b - 1) fmt.Println("b =", b) } func funca(a int) { funcb(a - 1) fmt.Println("a =", a) } func main() { funca(3) // 调用函数 fmt.Println("--------------> main") }
9、函数递归调用的流程
package main import "fmt" func test(a int) { // 函数终止调用的条件,非常重要 if a == 1 { fmt.Println("a =", a) return // 终止函数调用 } // 函数调用自身 test(a - 1) fmt.Println("a =", a) } func main() { test(3) fmt.Println("---------------> main") }
10、数字累加
package main import "fmt" // 实现1加到100 func test01() (sum int) { for i := 1; i <= 100; i++ { sum += i } return } func test02(i int) int { if i == 1 { return 1 } return i + test02(i-1) } func test03(i int) int { if i == 100 { return 100 } return i + test03(i+1) } func main() { var sum int sum = test01() fmt.Println("sum =", sum) sum = test02(100) fmt.Println("sum =", sum) sum = test03(1) fmt.Println("sum =", sum) }
11、函数类型
package main import "fmt" func add(a, b int) int { return a + b } func minus(a, b int) int { return a - b } // 函数也是一种数据类型,通过type给一个函数类型起名 // FuncType它是一个函数类型 type functype func(int, int) int // 没有函数名字,没有{} func main() { var result int result = add(1, 1) // 传统调用方式 fmt.Println("result1 =", result) // 声明一个函数类型的变量,变量名叫ftest var ftest functype ftest = add // 是变量就可以赋值 result = ftest(10, 20) // 等价于add(10, 20) fmt.Println("result2 =", result) ftest = minus result = ftest(10, 5) // 等价于minus(10, 5) fmt.Println("result3 =", result) }
12、回调函数
package main import "fmt" type functype func(int, int) int // 加法 func add(a, b int) int { return a + b } // 减法 func minus(a, b int) int { return a - b } // 乘法 func mul(a, b int) int { return a * b } // 回调函数,函数有一个参数是函数类型,这个函数就是回调函数。 // 计算器,可以进行四则远算 // 多态,多种形态,调用同一个接口,不同的表现,可以实现不同表现,加减乘除 // 现有想法,后面再实现功能 func calc(a, b int, ftest functype) (result int) { fmt.Println("calc") result = ftest(a, b) // 这个函数还没有实现 // result = add(a, b) // add()必须先定义后,才能调用 return } func main() { a := calc(1, 2, add) fmt.Println("a =", a) }
13、匿名函数和闭包
package main import "fmt" func main() { a := 10 name := "zhouwanchun" // 匿名函数,没有函数名字,函数定义,还没有调用 f1 := func() { // 自动推导类型 fmt.Println("a =", a) fmt.Println("name =", name) } f1() fmt.Println("-----------------------------") // 给一个函数类型起别名 type FuncType func() // 函数没有参数,没有返回值 // 声明变量 var f2 FuncType f2 = f1 f2() fmt.Println("-----------------------------") // 定义匿名函数,同时调用 func() { fmt.Printf("a = %d, name = %s\n", a, name) }() // 后面的()代表调用此匿名函数 fmt.Println("-----------------------------") // 带参数的匿名函数 f3 := func(i, j int) { fmt.Printf("i = %d, j = %d\n", i, j) } f3(1, 2) fmt.Println("-----------------------------") // 定义匿名函数,同时调用 func(i, j int) { fmt.Printf("i = %d, j = %d\n", i, j) }(10, 20) fmt.Println("-----------------------------") // 匿名函数,有参有返回值 x, y := func(i, j int) (max, min int) { if i > j { max = i min = j } else { max = j min = i } return }(10, 20) fmt.Printf("x = %d, y = %d\n", x, y) }
14、闭包捕获外部变量的特点
package main import "fmt" func main() { a := 100 name := "zhouwanchun" fmt.Printf("外部:a = %d, name = %s\n", a, name) func() { // 闭包以引用方式捕获外部变量 a = 666 name = "eric" fmt.Printf("内部:a = %d, name = %s\n", a, name) }() // ()代表直接调用 fmt.Printf("外部:a = %d, name = %s\n", a, name) }
15、闭包的特点
package main import "fmt" // 函数的返回值是一个匿名函数,返回一个函数类型 func test01() func() int { var x int // 没有初始化,值为0 return func() int { x++ return x * x } } func test02() int { // 函数被调用时,x才分配空间,才初始化为0 var x int // 没有初始化,值为0 x++ return x * x // 函数调用完毕,x自动释放 } func main() { // 返回值为一个匿名函数,返回一个函数类型,通过f来调用返回的匿名函数,f来调用闭包函数。 // 它不关心这些捕获了的变量和常量是否已经超出了作用域。 // 所以只有闭包还在使用它,这些变量就还会存在。 f := test01() fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println("--------------------") fmt.Println(test02()) fmt.Println(test02()) fmt.Println(test02()) fmt.Println(test02()) fmt.Println(test02()) fmt.Println(test02()) fmt.Println(test02()) }
16、defer的使用
package main import "fmt" func main() { // defer 延迟调用,main函数结束前调用 defer fmt.Println("show databases ;") fmt.Println("mysql -uroot -p123456 -S /data/3306/mysql.sock") }
17、多个defer的执行顺序
package main import "fmt" func test(x int) { result := 100 / x fmt.Println("result =", result) } func main() { defer fmt.Println("show databases ;") defer fmt.Println("mysql -uroot -p123456 -S /data/3306/mysql.sock") // 调用一个函数,导致内存出问题 defer test(2) defer fmt.Println("先执行我") }
18、defer和匿名函数结合使用
package main import "fmt" func main() { a := 10 b := 20 defer func(a, b int) { fmt.Printf("a = %d, b = %d\n", a, b) }(a, b) // ()代表调用此匿名函数,把参数传递过去,已经先传递参数,只是没有调用 defer func(a, b int) { fmt.Printf("a = %d, b = %d\n", a, b) }(30, 40) // ()代表调用此匿名函数,把参数传递过去,已经先传递参数,只是没有调用 a = 111 b = 222 fmt.Printf("外部:a = %d, b = %d\n", a, b) c := 10 d := 20 defer func() { fmt.Printf("c = %d, b = %d\n", c, d) }() // ()代表调用此匿名函数 c = 111 d = 222 fmt.Printf("外部:c = %d, d = %d\n", c, d) }
19、获取命令行参数
package main import "fmt" import "os" func main() { // 接收用户传递的参数,都是以字符串方式传递 list := os.Args n := len(list) fmt.Println("n =", n) // xxx.exe a b for i := 0; i < n; i++ { fmt.Printf("list[%d] = %s\n", i, list[i]) } for i, data := range list { fmt.Printf("list[%d] = %s\n", i, data) } } // F:\go\day01>go build 1_zhouwanchun.go // F:\go\day01>1_zhouwanchun.exe a b c // F:\go\day01>1_zhouwanchun.exe a b c // n = 4 // list[0] = 1_zhouwanchun.exe // list[1] = a // list[2] = b // list[3] = c // list[0] = 1_zhouwanchun.exe // list[1] = a // list[2] = b // list[3] = c
20、局部变量
package main import "fmt" func test() { a := 10 fmt.Println("a = ", a) } func main() { // 定义在{}里面的变量就是局部变量,只能在{}里面有效 // 执行到定义变量那句话,才开始分配空间,离开作用域自动释放 // 作用域,变量其作用的范围 a := 111 { a = 10 fmt.Println("a = ", a) } // a = 222 if flag := 3; flag == 3 { fmt.Println("flag = ", flag) } // flag = 4 }
21、全局变量
package main import "fmt" func test() { fmt.Println("test a =", a) } // 定义在函数外部的变量是全局变量 // 全局变量在任何地方都能使用 var a int func main() { a = 10 fmt.Println("a =", a) test() }
22、不同作用域同名变量
package main import "fmt" var a byte // 全局变量 func main() { fmt.Printf("a的类型是%T\n", a) // uint8 var a int // 局部变量 // 不同作用域,允许定义同名变量 // 使用变量的原则,就近原则 fmt.Printf("a的类型是%T\n", a) // int { var a float32 fmt.Printf("a的类型是%T\n", a) // float32 } test() } func test() { fmt.Printf("a的类型是%T\n", a) // uint8 就是byte }
23、导入包
package main // 忽略此包 import _ "fmt" func main() { } // 给包名起别名 import io "fmt" func main() { io.Println("this is a test.") } // .操作 import . "fmt" // 调用函数,无需通过包名 import . "os" func main() { Println("this is a test.") Println("os.Args =", Args) } // 方式1 import "fmt" // 导入包,必须使用,否则编译不过 import "os" // 方式2 import ( "fmt" "os" ) func main() { fmt.Println("this is a test.") fmt.Println("os.Args =", os.Args) }
24、Go的工程管理
// 同级目录 1.分文件编程,多个源文件,必须放在src目录 2.设置GOPATH环境变量:为src所在的上一级绝对路径 3.同一个目录,包名必须一样 4.go env查看go相关的环境路径 5.同一个目录,调用别的文件的函数,直接调用即可,无需包名引用 [root@linux-node2 ~]# tree src src ├── main.go └── test.go 0 directories, 2 files src main.go package main func main() { test() } test.go package main import "fmt" func test() { fmt.Println("this is a test.") } // 不同目录 1.不同目录,包名就不一样 2.调用不同包里面的函数,格式:包名.函数名() 3.调用别的包的函数,这个包的函数名字如果首字母是小写,无法让别人调用。要想别人能调用,必须首字母大写。 4.只要你导入一个包,Golang就会先执行被导入包的init()函数,然后在执行你的主程序main()函数 执行循序:被导出包的init()函数--->本身初始化init()函数--->main()入口函数 [root@linux-node2 ~]# tree src src ├── calc │ └── calc.go └── main.go 1 directory, 2 files src calc calc.go package calc import "fmt" func init() { fmt.Println("this is calc init.") } func Add(a, b int) int { return a + b } main.go package main import ( "fmt" "calc" ) func init() { fmt.Println("this is main init.") } func main() { a := calc.Add(10, 20) fmt.Println("a =", a) } 原来是go build src/main.exe 可执行程序 src: 放源代码 如果有多个文件或多个包 1.配置GOPATH环境变量,配置src同级目录的绝对路径 如:C:\Users\zhouwanchun\Desktop\code\go\src\ 2.自动生成bin或pkg目录,需要使用go install命令(了解) 除了要配置GOPATH=环境变量,还要配置GOBIN=环境变量 src : 放源代码 bin : 放可执行程序 pkg : 放平台相关的库
Go语言 函数,工程管理的更多相关文章
- go语言入门(5)工程管理
在工程中不会简单到只有一个源代码文件,且源文件之间会有相互的依赖关系,早期Go语言使用makefile作为工程管理的临时方案,后来的Go命令行工具的革命性之处在于彻底消除了工程文件的概念,完全用目录结 ...
- go语言20小时从入门到精通(六、工程管理)
在实际的开发工作中,直接调用编译器进行编译和链接的场景是少而又少,因为在工程中不会简单到只有一个源代码文件,且源文件之间会有相互的依赖关系.如果这样一个文件一个文件逐步编译,那不亚于一场灾难. Go语 ...
- go语言基础之工程管理和工作区介绍
1.工程管理 在实际的开发工作中,直接调用编译器进行编译和链接的场景是少而又少,因为在工程中不会简单到只有一个源代码文件,且源文件之间会有相互的依赖关系.如果这样一个文件一个文件逐步编译,那不亚于一场 ...
- Golang编程的工程管理
Golang编程的工程管理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- JVM内存管理------JAVA语言的内存管理概述
引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...
- 使用BLADE构建c++工程管理
使用BLADE构建c++工程管理 字数764 阅读2753 评论2 喜欢4 一. c++工程依赖管理 之前在百度一直使用comake2构建c++项目,十分方便.免去了手写Makefile的痛苦,很多项 ...
- C语言的内存管理
C语言的内存管理 转载:http://blog.csdn.net/wind19/article/details/5964090 对于一个C语言程序而言,内存空间主要由五个部分组成代码段(.text ...
- 动态修改 C 语言函数的实现
Objective-C 作为基于 Runtime 的语言,它有非常强大的动态特性,可以在运行期间自省.进行方法调剂.为类增加属性.修改消息转发链路,在代码运行期间通过 Runtime 几乎可以修改 O ...
- C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针
C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针 (1)开辟的内存没有释放,造成内存泄露 (2)野指针被使用或释放 (3)非法释放指针 (1)开辟的内存没有释放.造成内存泄露,以下的样 ...
随机推荐
- Cassandra -- Cassandra 3.0版本安装
============================================================ 服务器信息 搭建三节点的Cassandra群集: SERVER1: 192.1 ...
- Spring Cloud 与 Dubbo、Spring Cloud 与 Docker、Spring Cloud 与 Kubernetes 比较
出处:http://dockone.io/article/4142
- AES 加解密 Java实现
package com.smt.cipher.symmetry; import java.nio.charset.Charset; import java.security.SecureRandom; ...
- LOJ 2743(洛谷 4365) 「九省联考 2018」秘密袭击——整体DP+插值思想
题目:https://loj.ac/problem/2473 https://www.luogu.org/problemnew/show/P4365 参考:https://blog.csdn.net/ ...
- postman测试post请求参数为json类型
1. 设置Headers Content-Type类型为application/json 2.Body 设置如下.请求的数据类型为Json格式
- Go 并发控制--WaitGroup的使用
开发过程中,经常task之间的同步问题.例如,多个子task并发完成一部分任务,主task等待他们最后结束. 在Go语言,实现同步的一种方式就是WaitGroup. Example package m ...
- kafka_2.11-0.8.2.1生产者producer的Java实现
转载自:http://blog.csdn.net/ch717828/article/details/50818261 1. 开启Kafka Consumer 首先选择集群的一台机器,打开kafka c ...
- hadoop 2.7.1安装和配置
一.安装环境 硬件:虚拟机 操作系统:Centos 6.4 64位 IP:192.168.241.128主机名:admin安装用户:root 二.安装JDK 安装JDK1.7或者以上版本.这里安装jd ...
- verilog代码 想法验证---与寄存器输出有关
verilog代码 想法验证---与寄存器输出有关 1. module test_mind( input wire clk, input wire reset, input wire i, outpu ...
- 【转】用python比对数据库表数据的脚本
最近在做一个数据库异构复制的项目,客户表示需要一个数据比对的工具,我就自己写了一个异构数据库的比对python脚本.这个比对脚本只能比对数量,不能比对具体的记录.使用的sql语句也是最基础的selec ...