函数高级
给类型重命名:
函数的参数和返回值都是类型的一部分,函数可以赋值给一个变量
1. 例:type MyFunc func(int, int) int
MyFunc就是我们将func(int, int) int重新定义了一下类型,以后在定义函数类型的是时候直接使用MyFunc就是代替了func(int, int) int
2.例:type Myint =int
Myint只是我们将int赋值给了Myint,并不是重新定义
在之后的使用中,Myint的参数和int的参数是可以进行运算的
type MyFunc func(int, int) int
type Myint = int
func test3(a func()) MyFunc {
a()
return func(x, y int) int {
return x + y
}
}
函数可变长参数
在go语言中函数时可以使用可变长参数来接收不定数量的参数。可变长参数由省略号 ...
和类型名组成,例如:‘ ...int
’表示一个接受任意数量的int
类型参数的可变长采纳数。
- 函数使用可变长参数时,可以像普通函数一样使用他们。可变长采纳数实际上就是一个切片,函数可以通过循环遍历切片来处理他们。
举个例子:
func sum(num ..int)int{
total :=0
for _,num :=range nums{
total +=num
}
return total
}
func mani(){
fmt.Println(sum(1,2,3)) // 输出:6
fmt.Println(sum(4,5,6,7)) //输出 22
fmt.Println("%T",num) // 类型是:int类型切片 []int
}
- 在上面的例子中,‘sum’函数使用可变长参数 ‘nums ...int’来接收任意数量的整数参数。在函数中,使用‘range’循环遍历‘nums’切片,计算他们的总和并返回,在‘main’函数中,我们使用‘sum’函数分别计算传递给他们的两个整数序列的总和。
defer关键字
-
defer
是 Go 语言中的一个关键字,用于注册一个函数调用,在函数返回时才被执行。 -
在 Go 语言中,函数可以通过
defer
关键字注册一个延迟执行的函数调用,这个函数会在包含它的函数返回时执行。使用defer
可以将一些必须要执行的代码(如释放资源、关闭文件等)放在函数结束前执行,以避免遗漏或者因为某些原因而忘记执行这些代码。defer
还可以被用来在出现异常时处理一些清理工作。 -
defer
关键字后面跟着要执行的函数或方法的调用。在函数执行到defer
语句时,被调用的函数并不会立即执行,而是会被放入一个栈中,等到函数执行完毕返回时再执行。如果函数在执行过程中出现了 panic,那么这些被延迟的函数也会在 panic 发生时按照后进先出的顺序执行。
延迟调用:;当前函数所有代码都执行完毕之后,在执行defer的内容,先注册,后调用,如果有两个defer,先写的defer后执行(类似是先进后出)
** 例子:**
func main(){
defer fmt.Println("Hello")
fmt.Println("World")
}
例子总结:
-
上面的代码会先输出 "World",然后再输出 "Hello"。因为
defer
的执行顺序是后进先出,所以 "Hello" 会在 "World" 之后输出。 -
需要注意的是,
defer
中注册的函数或方法的实参是在注册时就会被求值,而不是在函数返回时再被求值。这意味着,如果函数执行过程中发生了变量的改变,那么被注册的函数调用时使用的是当前变量的值,而不是注册时的值。
包的使用
在python中的 模块和包
- 模块是一个py文件
- 包是一个又__init__文件的文件夹
# 在go中 包是在一个文件夹下,这个文件夹下所有Go文件的第一行都需要声明包
--就是一堆Go文件的组合
使用步骤:
- 新建一个文件夹,写多个go文件,包名必须是一致的
PS:
1. 在包的内部,想要被其他的包下使用这个包中的变量,函数,就需要将函数,变量 的'首字母大写'
2.在包的内部的变量,函数名只能命名一次
3.包内部的所有东西只要是在这个包的内部都是可以直接使用的
4.包的名字可以和这个文件名不一样,但是一个文件夹下只能有一个包
5.导入包,是按照路径进行导入的,如果不重命名的话,就是文件夹必须和包名一样
如果文件夹跟包名不一样,就需要重命名,可以命名成任意的,但是一般是使用包名(包内部命名的包名)
import ff "go_03/utils"
也可以是再这个包下重新命名
import qqq "go_03/utils"
以后在使用包名调用即可
6.包内部中有init函数可以被定义多次,只要导入包,就会依次执行 包中的init函数
7.导入包,必须使用,不使用的话就会报错,现在不使用,只想执行init ,就可以
import _ "go_03/utils"
8.一个文件夹下可以再创建一个文件夹,可以在这个文件夹下再创建一个包,但是这两个文件夹是没有联系的,只是简单的文件的层级关系。
9.使用的Go mod模式,从1.11后都是使用这种模式,项目路径下会有一个go.mod文件,不要动它
// 早期有个go path 模式,已经被弃用了,它在导入包的时候,不是从项目路径下开始导入的,而是从go path 的src 路径下路径开始导入的
包的使用:
gin官网:https://pkg.go.dev/github.com/gin-gonic/gin#section-readme
go sdk 内置包,自定义包,第三方包
-gin : 可以开启一个web服务
- 安装第三方包
# 使用 gin
gin我们想要下载就是子啊GitHub上下载,会很慢,而且可能会出现下载不了的现象。所以我们可以使用配置代理: 使用七牛云代理
局部配置: Goland 中:
GOPROXY=https://goproxy.cn,direct
全局配置: 更改全局 go env
安装:go get github.com/gin-gonic/gin
代码例子:
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/*")
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"code": "100",
"meassge": "发送成功",
})
})
r.Run()
流程控制语句
if -else
# 语法格式
if 条件{
}else if 条件{
}else{
}
PS:{}必须挨着条件,否则就会报错
循环:
在go中只有for循环
在python中 有while for
java中 有while ,for ,do while
go中能是用for实现while循环功能
案例:
package main
import "fmt"
// 循环
func main() {
// 1.基本语法 循环打印0-9
/* for i := 0; i < 10; i++ {
fmt.Println(i)
}*/
// 2. i 的作用域范围只会在for 内部有效
//i := 0
//for i := 0; i < 10; i++ {
// fmt.Print(i) // 0123456789
//}
//fmt.Println(i) //0
// 3.省略第一部分 分号不能省
//i := 0
//for ; i < 10; i++ {
// fmt.Println(i) // 0,1,2,3,4,5,6,7,8,9
//}
//fmt.Println(i) // 10
// 4.省略第三部分 分号也不能省
//for i := 0; i < 10; {
// fmt.Println(i)
// i++
//}
// 5. 省略第一部分和第三部分,分号也不用写了
//i := 0
//for i < 10 {
// fmt.Println(i)
// i++
//}
// 6.for 条件{} 写成while循环 死循环
//for true {
// fmt.Println("aaaa")
//}
// 7. 死循环
//for {
// fmt.Println("bbbbbb")
//}
// 8.上面都是基于索引的循环,下面这个案例是基于迭代的
s := "lover中国"
//for i, v := range s {
// fmt.Println(i)
// fmt.Println(string(v))
//}
for i := 0; i < len(s); i++ {
fmt.Println(string(s[i])) // 打印的就是乱码
}
}
switch
- 在go语言中,
switch
语句用于根据不同的条件执行不同的代码块。它可以被认为是一个更灵活和可读性更高的if-else
语句。
switch的语句基本语法:
switch expression {
case value1:
// 执行代码块1
case value2:
// 执行代码块2
...
default:
// 执行默认代码块
}
详解:其中,expression
是要被检查的表达式,value1
、value2
等是与表达式进行比较的值。如果expression
的值等于其中一个case
后面跟随的值,那么与该case
匹配的代码块将被执行。如果没有任何一个case
匹配,则执行default
代码块(如果有)。
简单案例:
import "fmt"
func main() {
num := 2
switch num {
case 1:
fmt.Println("这是数字1")
case 2:
fmt.Println("这是数字2")
default:
fmt.Println("不知道是什么数字")
}
}
详解:在上面的示例中,如果num
等于1,那么输出"这是数字1";如果num
等于2,那么输出"这是数字2";如果num
不是1、2,那么输出"不知道是什么数字"。
Switch的多中使用方式:
package main
import "fmt"
func main() {
//num := 2
//switch num {
//case 1:
// fmt.Println("这是数字1")
//case 2:
// fmt.Println("这是数字2")
//default:
// fmt.Println("不知道是什么数字")
//
//}
// 多表达式判断
//num := 38
//switch num {
//case 3, 4, 5:
// fmt.Println("这是数字1")
//case 2, 8, 9, 20:
// fmt.Println("这是数字2")
//default:
// fmt.Println("不知道是什么数字")
//
//}
// 无表达式
//num := 48
//switch {
//case num > 40:
// fmt.Println("数字大于40")
//case num > 60 && num < 40:
// fmt.Println("数字大于60")
//default:
// fmt.Println("不知道是什么数字")
//}
// Fallthrough 在默认的情况下,每个条件之间执行完毕默认会加上break
// 但是也可以不用加,其他的语言是要加的,其他得语言去掉break就会执行
// 下一个 case
//在go 中要无条件执行下一个case ,及需要使用到 fallthrough
num := 38
switch {
case num < 20:
fmt.Println("数字小于20")
case num < 40 || num > 30:
fmt.Println("这是数字小于40大于30")
fallthrough
default:
fmt.Println("不知道是什么数字")
就会打印
// 这是数字小于40大于30
//不知道是什么数字
}
}
数组
- 在go语言中,数组是一种用于存储固定数量的数据结构。数组中的每一个元素都有一个唯一的索引,可以使用这个索引来访问特定的元素。
创建数组:
- 想要创建一个数组,需要指定数组的长度和元素的类型如下:
var arr[3] int
这就是创建一个包含3个整数的数组
- 也可以使用字面量初始化数组
arr :=[3]int{1,2,3}
访问数组元素
- 想要访问数组元素,可以使用数组的索引。例如。想要访问arr数组的第一个元素,可以使用:
fmt.Println(arr[0]) // 就会输出1
遍历数组
- 想要遍历数组,可以使用for循环和数组的长度。例如:下面就是遍历arr数组中所有的元素,
for i := 0; i<len(arr); i++{
fmt.Println(arr[i])
}
// 也可以使用range关键字来遍历数组,它会返回数组的索引和值:
for index,value := range arr{
fmt.Println(index,value)
}
数组的长度
- 想要获得数组的长度,可以使用len函数。例如:
fmt.Println(len(srr)) // 输出3
数组切片
- 数组可以使用切片来访问一部分的元素,切片是一个指向数组的指针,它包含一个开始索引和一个结束索引。
- 如下代码创建了一个包含arr数组的前两个元素的切片:
slice :=arr[0:2]
// 也可以使用省略来简化切片操作,如下
slice := arr[:2]
数组的修改
- 可以通过索引来修改数组的元素,如下将数组的第一个元素修改为10,
arr[0]=10 // 输出 [10,0,0]
多维数组
-
多维数组是指数组中包含其他的数组的数组。他们通常用于表示二维表格和矩阵等复杂数据结构,在go语言中,可以创建任意维度的数组,只需要指定每一维度的长度即可。
-
go语言可以创建多维数组,如下:
创建一个包含3行4列的二维数组:
var matrix[3][4]int
// 这个数组包含3个子数组,每个子数组包含4个整数。要访问数组中的元素,需要使用两个索引,一个表示行数,另一个表示示例数,如下:
value :=matrix[1][2]
//多维数组的初始化可以使用嵌套的花括号:如下:
matrix :=[3][4]int{
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},
}
// 这个数组的每一个子数组包含4个整数,分别是初始化为
1、2、3、4,5、6、7、8和9、10、11、12。
//在go语言中,多维数组的每个维度都可以单独遍历,可以使用嵌套的for循环来遍历多维数组的每一个元素,如下遍历所有matrix数组的所有元素
for i := 0; i<len(matrix);i++{
for j:=0; j<len(matrix[i]);j++{
fmt.Println(matrix[i][j])
}
}
ps:多维数组在一些算法和数据处理场景中非常有用,可以有效的表示和操作数据结构。
标签:03,入门,int,fmt,Println,num,数组,Go,go
From: https://www.cnblogs.com/qiguanfusu/p/17357087.html