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文件的时候,包名必须一致

总结

  1. 包内部,大写开头,表示导出 变量,函数。。。
  2. 包内部的变量函数,只能定义一次
  3. 包内部的所有东西,在包内部直接使用
  4. 包名可以跟文件夹名不一样,但是一个文件夹下只能有一个包
  5. 导入包,按路径导入,如果不重命名,就是文件夹必须跟包名一样
    1. 如果文件夹跟包名不一样,要重命名,可以命名成任意的,但是我们叫了包名 import lqz "go_day03/utils"
    2. 可以命名成任意的包名 import qqq "go_day03/utils"
    3. 以后使用包名. 调用即可
  6. 包内的init函数,可以定义多次,只要导入包,就会依次执行init
  7. 导入包,必须使用,不使用就报错,现在就不用,只想执行init, import _ "go_day03/utils"
  8. 一个文件夹下可以再建文件夹建新的包,各个文件夹直接没有必然联系,只是文件夹层级关系(导入使用即可)
  9. 使用的go mod模式,从1.11后都是这种模式,项目根路径下会有一个go.mod

go path模式介绍

之前有个go path模式,已经弃用了,它的包导入,不是从项目路径下开始导入,而是从go path 的src路径下路径下开始导入

go 安装第三方包(以gin包为例)

go语言中的包目前没有同意的存储仓库,因此大部分的go包都是从github中下载的,也可以使用第三方代理下载

ps:github下载速度感人!

主流的代理

配置代理

1、配置局部代理(goland中启用代理)

打开设置界面后,先去找下图的界面是否跟你的界面一样(新版本会不一样),如果一样按照他的操作设置

img

如果你发现自己的界面跟上图的界面不一样,就参考这张图中的配置代理设置(需要手动输入)

img

还有一种设置方式

img

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结点组成的对象就是链表对象。火车的不同车厢之间都是通过挂钩连接的,当两个车厢之间脱钩之后,两个车厢就没有任何关系了。

img

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

请注意,这只是一个简单的链表实现,还有很多方面可以进行改进和优化。

posted @   wwwxxx123  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 起风了 买辣椒也用券
起风了 - 买辣椒也用券
00:00 / 00:00
An audio error has occurred.