go:函数高级、包的使用、if-else、循环、switch、数组
一、函数高级
1、函数的参数和返回值都是类型的一部分,函数可以赋值给一个变量,有两种情况:
test3 函数,接收一个参,参数是函数类型:没有参数没有返回值
test3 有返回值,返回值是个函数:函数有两个参数,一个返回值
有参数有返回值的带代码如下:
package main import "fmt" func main() { f := test3(func() { fmt.Println("被传入的函数") }) res := f(10, 19) fmt.Println(res) } func test3(a func()) func(int, int) int { a() return func(x, y int) int { return x + y } }
2、类型重命名
可以给类型重命名
如果 type Myint int 相当于我们新定义了一个类型,叫Myint
如果 type 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 } }
3、函数可变长参数
可以传任意长度的int类型参数
func test4(a ...int) { fmt.Println(a) //[3 4 5 6 7 7 8 89 9 99] 切片 fmt.Printf("%T", a) // 类型是 int类型切片 []int }
4、defer 关键字
package main import "fmt" func main() { //var a Myint = 9 //var b int = 19 //fmt.Println(a + b) //fmt.Println(6,3,4,5,5,6,76,7,8) // 完整定义 //var f MyFunc = test3(func() { // fmt.Println("被传入的函数") //}) //res := f(10, 19) //fmt.Println(res) // 3 可变长参数 //test4(3, 4, 5, 6, 7, 7, 8, 89, 9, 99) // 4 defer 延迟调用, 当前函数所有代码都执行完了,再执行defer的内容,先注册,后调用 ,先写的defer后来执行 //var a = 10 //defer func(i int) { // fmt.Println(i) // fmt.Println("我很帅") // //}(a) defer fmt.Println("我很帅") defer fmt.Println("我很帅222") //a = 99 fmt.Println("我不觉得") fmt.Println("我也不觉得") }
二、包的使用
python 模块和包
模块是一个py文件
包是一个文件夹 有 init
go的包
go中的包是在一个文件夹下,这个文件夹下所有go文件的第一行要声明包(一堆go文件的组合)
当我们在一个文件夹内编写多个go文件的时候,包名必须一致
总结
- 包内部,大写开头,表示导出 变量,函数。。。
- 包内部的变量函数,只能定义一次
- 包内部的所有东西,在包内部直接使用
- 包名可以跟文件夹名不一样,但是一个文件夹下只能有一个包
- 导入包,按路径导入,如果不重命名,就是文件夹必须跟包名一样
- 如果文件夹跟包名不一样,要重命名,可以命名成任意的,但是我们叫了包名 import lqz "go_day03/utils"
- 可以命名成任意的包名 import qqq "go_day03/utils"
- 以后使用包名. 调用即可
- 包内的init函数,可以定义多次,只要导入包,就会依次执行init
- 导入包,必须使用,不使用就报错,现在就不用,只想执行init, import _ "go_day03/utils"
- 一个文件夹下可以再建文件夹建新的包,各个文件夹直接没有必然联系,只是文件夹层级关系(导入使用即可)
- 使用的go mod模式,从1.11后都是这种模式,项目根路径下会有一个go.mod
go path模式介绍
之前有个go path模式,已经弃用了,它的包导入,不是从项目路径下开始导入,而是从go path 的src路径下路径下开始导入
go 安装第三方包(以gin包为例)
go语言中的包目前没有同意的存储仓库,因此大部分的go包都是从github中下载的,也可以使用第三方代理下载
ps:github下载速度感人!
主流的代理
- 阿里云 https://mirrors.aliyun.com/goproxy/(推荐使用)
- nexus社区 https://gonexus.dev
- goproxy.io的 https://goproxy.io/ (推荐使用)
- athens的公共服务 https://athens.azurefd.net
- 官方提供 https://gocenter.io https://proxy.golang.org
- 七牛云 https://goproxy.cn
配置代理
1、配置局部代理(goland中启用代理)
打开设置界面后,先去找下图的界面是否跟你的界面一样(新版本会不一样),如果一样按照他的操作设置
如果你发现自己的界面跟上图的界面不一样,就参考这张图中的配置代理设置(需要手动输入)
还有一种设置方式
2、配置全局代理
打开cmd界面或是goland中的terminal界面,输入下方命令
1.打开模块支持 go env -w GO111MODULE=on 2.取消代理 go env -w GOPROXY=direct 3.取消校验 go env -w GOSUMDB=off 设置不走 proxy 的私有仓库或组,多个用逗号相隔(可选) go env -w GOPRIVATE=git.mycompany.com,github.com/my/private 备注:-w 标记 要求一个或多个形式为 NAME=VALUE 的参数且覆盖默认的设置
gin包简介
gin包是一个框架,相当于python中的flask
安装gin包:
go get -u 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", "message": "成功", }) }) r.GET("/index", func(c *gin.Context) { c.HTML(200, "index.html", gin.H{"name": "刘清政", "age": 19}) }) r.Run() // listen and serve on 0.0.0.0:8080 }
这里我们不做具体讲解,但是我们可以看到他这里路由的注册也是类似django的,路由跟视图函数的内存地址绑定
三、if-else
#基本格式 if 条件{ }else if 条件{ }else{ }
ps:如果else和括号,不在同一行,会报错,他们算是一个整体,不能分割(比python中严格)
package main import ( "fmt" ) // if-else func main() { score := 55 if score >= 90 { fmt.Println("优秀") } else if score >= 80 && score < 90 { fmt.Println("良好") } else if score >= 60 { fmt.Println("及格") } else { fmt.Println("不及格") } }
四、循环
# python while for # go 只有 for循环 # java while ,for do while # go的for循环能实现while循环的功能
package main // 循环 func main() { // 1 基本语法 for关键字 定义变量i=0;i<10;i++{} 三部分都可以省略,但是一般会保留第二部分,第二部分是条件 //// 2 循环打印0--9 //for i := 0; i < 10; i++ { // fmt.Println(i) //} //fmt.Println(i) // i的作用域范围只在for内部有效 // 3 循环打印0--9 省略掉第一部分 分号不能省 //i := 0 //for ; i < 10; i++ { // fmt.Println(i) //} //fmt.Println(i) // 10 // 4 循环打印0--9 第三部分 分号不能省 //for i := 0; i < 10; { // fmt.Println(i) // i++ //} // 5 循环打印0--9 省略第一部分和第三部分 分号能省略 //i := 0 //for i < 10 { // fmt.Println(i) // i++ //} // 6 for 条件 {} while 循环 //for true { // fmt.Println("llll") //} // 死循环 //for { // fmt.Println("llll") //} //7 上面是基于索引的循环,这个案例是基于迭代的 s := "lqz国中" //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
switch 是一个条件语句,用于将表达式的值与可能匹配的选项列表进行比较,并根据匹配情况执行相应的代码块,优雅的替换掉else-if package main import "fmt" func main() { // 1 switch 基本使用 //score := 90 //switch score { //case 90: // fmt.Println("我是90") //case 80: // fmt.Println("我是80") //case 70: // fmt.Println("我是70") //} //// 2 default 的使用 //score := 99 //switch score { //case 90: // fmt.Println("我是90") //case 80: // fmt.Println("我是80") //case 70: // fmt.Println("我是70") //default: // fmt.Println("不知道") //} // 3 多表达式判断 //score := 66 //switch score { //case 90, 91, 92, 98, 99: // fmt.Println("我是90") //case 80, 88: // fmt.Println("我是80") //case 70: // fmt.Println("我是70") //default: // fmt.Println("不知道") //} // 4 无表达式 //score := 66 //switch { //case score > 90: // fmt.Println("我是90") //case score > 80 && score < 90: // fmt.Println("我是80") //case score >= 60: // fmt.Println("大于60") //default: // fmt.Println("不知道") //} //5 Fallthrough 默认情况下,每个条件之间完,默认加break,但是也不用加,其他语言要加,其他语言去掉break,会无条件执行下一个case // 要无条件执行下一个case,需要使用fallthrough score := 99 switch { case score > 90: fmt.Println("我是90") case score > 80 && score < 90: fmt.Println("我是80") fallthrough // 无条件执行下一个case case score >= 60 && score <= 80: fmt.Println("大于60") fallthrough default: fmt.Println("不知道") } }
六、数组
# 数组是同一类型元素的集合。例如,整数集合 5,8,9,79,76 形成一个数组。 # Go 语言中不允许混合不同类型的元素,例如包含字符串和整数的数组 # 数组是连续存储,存储同一个类型的数据结构
七、作业
python实现链表
链表的概念
1、链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,有一系列结点(地址)组成,结点可动态的生成。
我们可以把单链表类比成火车,每一列火车由若干个车厢组成,每个车厢就是一个Node结点,由多个Node结点组成的对象就是链表对象。火车的不同车厢之间都是通过挂钩连接的,当两个车厢之间脱钩之后,两个车厢就没有任何关系了。
Python 中没有内置的链表数据结构,但可以通过定义类来实现链表。
链表是一种数据结构,由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。相比于数组,链表的优势在于可以高效地进行插入和删除操作,但是访问元素需要从头开始遍历链表,因此访问元素的时间复杂度为 O(n)。
以下是一个简单的 Python 链表实现:
class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None def add_node(self, data): new_node = Node(data) if self.head is None: self.head = new_node else: current = self.head while current.next is not None: current = current.next current.next = new_node def print_list(self): current = self.head while current is not None: print(current.data, end=" ") current = current.next print()
上面的代码定义了一个 Node
类和一个 LinkedList
类。Node
类表示链表中的节点,包含一个数据元素和一个指向下一个节点的指针。LinkedList
类表示链表本身,包含一个指向链表头节点的指针。
LinkedList
类定义了两个方法:add_node()
用于向链表中添加节点,print_list()
用于打印链表中的所有元素。
以下是一个使用链表的例子:
my_list = LinkedList() my_list.add_node(3) my_list.add_node(1) my_list.add_node(4) my_list.add_node(1) my_list.add_node(5) my_list.add_node(9) my_list.print_list() # 输出:3 1 4 1 5 9
请注意,这只是一个简单的链表实现,还有很多方面可以进行改进和优化。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)