1 函数基础
//0 强调
在同一个包下,无论有多少go文件,函数名 和 变量名 不能重复
函数和变量 可以直接使用
//把一个包,当成一个大的go文件看待
go中,函数参数没有关键字参数一说,只能按照位置传递
//1 函数定义模板: 一个返回值时,直接写返回类型 不用加括号
func 函数名(参数名 类型, 参数名 类型)(返回值类型,返回值类型){
函数体内容
return 返回值1,返回值2
}
//2 函数使用:
函数名(参数, 参数) //跟定义位置无关,与python相同
//3 接受返回值时
// 1.需按照返回值类型,定义接受变量,故常用推导模式 或者 简略声明
res := test5(2,3)
var res = test5(2,3)
// 2.有几个返回值,需要用几个变量接受 不能使用一个变量接受 python中可以,该变量就是元祖类型
res1, res2 := test6(2,3)
// 3.有多个返回值,只需要使用其中一个,但其他返回值又必须接受,且go中定义了变量,就必须使用
采用 下划线 _ 接受,表示忽略该返回值 //python中,_ 也是个一个变量
忽略多个返回值,就多个_ 接受
res1,_ ,_:= test6(2,3)
//4 各种函数样式
//1.无参数,无返回值函数
func test1() {
fmt.Println("我是test")
}
//2.有参数,无返回值
func test2(a int,b string) {
fmt.Println(a, b)
}
//3.有参数无返回值,有多个相同类型参数 类型可以简写
func test3(a ,b int) {
fmt.Println(a+b)
}
//4.有参数无返回值,有多个相同类型参数,也有不同类型
func test4(a ,b int,msg string) {
fmt.Println(a+b)
fmt.Print(msg)
}
//5.多个参数,一个返回值 直接写返回类型 不用加括号
func test5(a, b int) int {
return a + b
}
//6.多个参数,多个返回值
func test6(a, b int) (int,string) {
return a + b, "计算成功"
}
//7.命名返回值: 返回值有名字
func test7(a,b int)(x int,y string) {
x=a+b // x和y,可以直接在函数内部用,不需要定义了
y="计算成功"
return // return时,可以不写x和y了 因为有名字了
}
2 函数高级
//1 匿名函数: 定义在函数内部,没有名字的函数
func main(){ // 定义在main函数内
func (){ // 没有名字的函数
fmt.Println("我是匿名函数")
}() // 函数定义完,必须使用,故加括号
}
//2 函数的返回值是函数
一门语言,若函数可以直接赋值给变量,那么该语言的函数就称之为 头等函数 或 函数是一等公民
func test2() func() {
//var a func() 定义一个变量a 类型是函数
//a = func(){ 再把该匿名函数 赋值给变量a
a := func() { // 或 直接用简略声明形式
fmt.Println("我是内层函数")
}
return a
}
//3 闭包函数:1 定义在函数内部 2 对外部作用域有引用
闭包函数就是多了一种给函数传参的方式,包进去的
//装饰器时闭包函数的典型应用,但go中没有@符号装饰器的语法糖
func test3(a int) func() { // 返回的就是一个 闭包函数
return func() { // 定义在函数内部
fmt.Println(a) // 对外部作用域的a 有引用
}
}
// 4 函数返回值为函数,该函数带参数
强调:类型名字必须一样,才叫同一个类型
func test4() func(msg string) { // 返回的就是一个有参数的函数
return func(msg string) {
fmt.Println(msg)
}
}
func test5(a int) func(b int,c string) { // 返回的就是一个有参数的 闭包函数
return func(b int,c string) {
fmt.Println(a)
}
}
//了解:套娃模式 5--7
//5 函数返回值为函数,返回的函数带参数,带返回值
func test6() func(a,b int) int { // 强调:func(a,b int) int 整体是一个 返回的类型
return func(a,b int) int {
return a+b
}
}
func test7() (func(a,b int) int , int) { // test7 返回值两个类型, 一个整体的,一个int
return func(a,b int) int {
return a+b
}, 99
}
func test8(a int) func(b int,c string) string { // 返回的就是一个有参数、有返回值的 闭包函数
return func(b int,c string) string {
fmt.Println(a)
return "返回了"
}
}
// 6 函数返回值为函数,返回的函数带参数,带返回值为函数
func test9() func(b int,c string) func() {
return func(b int,c string) func() {
fmt.Println(b)
return func() {}
}
}
// 7 函数参数为函数类型,返回值为带参数,带返回值的函数类型
func test10(a func()) func(b func(), c string) func() {
return func(b func(), c string) func() {
fmt.Println(a)
return func() {}
}
}
//8 给变量类型重命名
type MyFunc func(b func(), c string) func() // 讲这个整体的返回类型,重命名为 MyFunc
func test11(a func()) (MyFunc,int) {
return func(b func(), c string) func() {
fmt.Println(a)
return func() {}
},99
}
//9 函数的可变长参数,可以传任意数量的int类型 参数
func test12(a... int) {
fmt.Println(a) // 这个a 就是一个切片类型
}
package main
import "fmt"
// 函数高级
func main() {
// 2 函数返回值是函数 使用
// var a func()=test2()
a :=test2()
fmt.Println(a) // 打印返回函数的内存地址
a() // 返回的函数 调用
// 3 返回闭包函数 使用
res:=test3(99)
fmt.Println(res) // 打印返回的闭包函数的内存地址
res() // 返回的闭包函数 调用
// 9 函数的可变长参数 使用
test12(1,2,3,4,5,6,7,8)
}
变量作用域范围
package main
import "fmt"
//在同一个包下,函数名不能重名
//变量的作用域范围: 全局变量,全局有效,任何位置修改,就都会改了
//eg1:
var a int
func main() {
fmt.Println(a) //0
a=19
fmt.Println(a) //19
test1() //99
fmt.Println(a) //99
}
func test1() {
a=99
fmt.Println(a)
}
//eg2: //先找局部,再找全局
var a int
func main() {
var a int
fmt.Println(a) //0
a=19
fmt.Println(a) //19
test1() //0
fmt.Println(a) //19
}
func test1() {
fmt.Println(a)
}
3 包
# 1 包: 类似模块的意思
# 2 总结:
1.一个文件夹放了很多go文件,除了main包以外,建议包名就叫文件夹名
2.这个文件夹下的go文件,包名都必须一样
3.同一个包下,变量和函数只能定义一次,不能重名
4.同一个包下,变量和函数可以直接使用
5.包内的函数或变量,想让外部包使用,必须首字母大写
6.如果用小写字母开头,只能在包内部用
# 4 包导入的几种方式
-import "day02/mypackage"
-给包重命名
import 名字 "day02/mypackage"
名字.变量/函数
-包只导入,不使用
import _ "day02/mypackage"
### go path 和 go module
# 1.11前,只有go path模式
-go 项目的所有源代码,包括第三方,必须放在go path的src路径下
-go get 第三方包名
# python都放在pypi上,而go语言没有一个专门的包管理网站,故大家都放在github
# eg: go get github.com/gin-gonic/gin
# 把项目源代码直接下载到了 本地的go path的src路径下
-该方式的包导入是从go path的src路径下开始检索
# 1.15后,go module可以正式使用
-项目可以放在任意路径下,项目路径下有个go.mod,里面记录了项目所依赖的第三方包
-以后都用这种 # 默认也是这种
# 原来是go path 都过渡到 go module
-采用go path模式的项目,转变成使用 go modeule模式
直接在命令行中敲:go mod init 项目名字 # 项目下会多一个go.mod,就可以正常用了
4 if else-条件判断
//1 语法
if 变量定义; 条件 { //条件和大括号必须在一行上
符合条件执行
}else if 条件 {
}else{
}
//2 注意
1.条件和大括号必须在一行上
2.条件部分可以写变量定义(简约声明模式),但是作用域范围只在判断内有效
//3 拓展
其实所有编程语言,每行结束都有一个分号 ; //java现在都有
但为了节约代码,默认都是取消了
通过编译器或解释器 读取到每行尾的换行符时,自动添加上分号 ;
这就是为啥条件和大括号必须在一行,也是变量定义后 有分号的原因
不在一行,会自动加上分号,不符合格式了
package main
import "fmt"
func main() {
//eg1:
var score = 100
if score >= 90 {
fmt.Println("优秀");
}else if score >=80 {
fmt.Println("良好");
}else {
fmt.Println("啥也不是")
}
fmt.Println(score)
//eg2: 使用较多
if score:=99; score>=90 {
fmt.Println("优秀");
}else if score >=80{
fmt.Println("良好");
}else {
fmt.Println("啥也不是")
}
fmt.Println(score)
}
5 for循环
//1 语法
for 变量定义; 条件; 自增或自减 { // 三部分都可以省略
循环体内容
continue 或 break
}
//2 注意
1.go只有for循环,没有while循环,但是能完成while循环的功能
2.for循环是基于索引的循环 但py中不支持,都是基于迭代的循环
3.go 和 java 基于索引和基于迭代的循环 两种都支持
package main
import "fmt"
func main() {
//案例:打印0-9
//第一种:完整三部分
for i:=0; i<10; i++ {
fmt.Println(i)
}
//第二种:省略第一部分 区别在作用域范围
i:=0
for ; i<10; i++ {
fmt.Println(i)
}
//第三种:只省略第三部分
for i:=0; i<10; {
fmt.Println(i)
i++
}
//第四种:省略第一和第三部分,分号可以不写了
i := 0
//for ; i < 10; {
for i<10 { // 就相当于while循环了
fmt.Println(i)
i++
}
//第五种:三部分都省略 ---> 死循环
for {
fmt.Println("死循环")
}
//第六种:步长
//for i:=9; i>=0; i=i-2 {
for i :=9; i>=0; i-=2 {
fmt.Println(i)
}
//第七种 break 和 continue
for i := 0; i < 10; i++ {
// 打到5就不打印了
fmt.Println(i)
if i>=5{
break // 直接终止整个循环
}
}
for i := 0; i < 10; i++ {
// 打到5就不打印了
if i==5{
continue // 终止本次,直接进入下次
}
fmt.Println(i)
}
}
6 switch
//switch : 优雅的替换掉if-else
package main
import "fmt"
func main() {
//第一种:基本使用: 符合case(某个条件),就会执行下面的代码
var score = 80
switch score {
case 90:
fmt.Println("90分")
case 80:
fmt.Println("80分")
case 70:
fmt.Println("70分")
}
//第二种:default: 默认情况
//default不一定只能出现在 switch 语句的最后,它可以放在switch语句的任何地方
var score = 88
switch score {
case 90:
fmt.Println("90分")
case 80:
fmt.Println("80分")
case 70:
fmt.Println("70分")
default:
fmt.Println("都不符合")
}
//第三种:无表达式的switch: 等同于switch true,并且每个case表达式都被认定为有效
var score = 8
switch {
case score >= 90:
fmt.Println("优秀")
case score >= 80:
fmt.Println("良好")
case score >= 60:
fmt.Println("及格")
default:
fmt.Println("不及格")
}
//第四种:多条件判断: 一个选项多个表达式,表示'或者' 符合其中一个即可
var score = 88
switch score {
case 3, 4, 5, 6, 90:
fmt.Println("优秀")
case 7, 8, 9:
fmt.Println("良好")
case 10, 11, 12:
fmt.Println("及格")
default:
fmt.Println("不及格")
}
//第五种:Fallthrough: 在已经执行完成的case之后,把控制权转移到下一个case
在Go中,每执行完一个case后,会从switch语句中跳出来,不再做后续case的判断和执行
其他语言中,switch符合条件时,执行case内部的代码,但是结尾必须加一个break,否则会无条件执行下一个case内的语句
// 注意:
1.fallthrough 只能加在case内部,表示无条件执行下一个case内的语句
2.fallthrough 应该是case子句中的最后一个语句,在其他位置会报错
var score = 90
switch score {
case 90:
fmt.Println("优秀")
fallthrough // 打印结果: "优秀" 和 "良好"
case 80:
fmt.Println("良好")
case 70:
fmt.Println("及格")
default:
fmt.Println("不及格")
}
}
标签:02,函数,int,fmt,Println,switch,func,Go,返回值
From: https://www.cnblogs.com/Edmondhui/p/17119802.html