首页 > 其他分享 >Go入门基础03

Go入门基础03

时间:2023-04-26 19:56:39浏览次数:48  
标签:03 入门 int fmt Println num 数组 Go go

函数高级

给类型重命名:

	函数的参数和返回值都是类型的一部分,函数可以赋值给一个变量


 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是要被检查的表达式,value1value2等是与表达式进行比较的值。如果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

相关文章

  • SpringSecurity从入门到精通:认证成功处理器&认证失败处理器
    认证成功处理器  认证失败处理器  ......
  • Golang - 5 Golang的流程控制:if/else、for、switch
    5流程控制目录5流程控制1if/else1.1语法2for2.1语法2.2简单写法与实现while的功能2.3基于迭代的循环、基于索引的循环3switch3.1switch的基本使用3.2各种形式1if/else1.1语法 //基本形式if条件1{ }else条件2{ }else{ }多个分支age:=......
  • Django模板层 (变量分配 过滤器 标签 继承和导入 自定义过滤器、标签及inclusion_ta
    目录一、模板变量分配定义 在后端变量的值通过模板语法传到前端符号{{}}:主要与数据值相关{%%}:主要与逻辑相关模板语法注意点:1.针对需要加括号调用的名字django模板语法会自动加括号调用你只需要写名字就行2.模板语法的注释{##},前端浏览器是无法查看的,因为它要先......
  • django token 认证 简单记录
    classUser(AbstractUser):username=models.CharField(max_length=20,unique=True,primary_key=True,verbose_name="用户名")email=models.EmailField(max_length=256,null=False,verbose_name="邮箱",blank=True)pass......
  • go语言 函数高级、包的使用、if-else、循环、switch、数组
    函数高级//函数1没有参数没有返回值fun函数名(){}2有参数没有返回值fun函数名(aint){}3多个参数同一种类型,可以简写fun函数名(a,bint){}4多个参数同一种类型,有返回值可以简写fun函数名(a,bint)int{retruna+b}5多个返回值fun......
  • Django 查询数据库不释放内存的情况
    查询结果未及时清空如果查询结果较大,可能会占用很多内存。在使用完查询结果后,应该及时清空,以释放占用的内存。可以通过将查询结果赋值给一个变量,然后使用del关键字删除变量来清空查询结果。例如:result=MyModel.objects.all()#使用查询结果...#清空查询结果delresul......
  • CVPR'23|向CLIP学习预训练跨模态!简单高效的零样本参考图像分割方法
    前言 本文提出了一种zero-shot的Referringimagesegmentation方法,该方法利用了来自CLIP的pre-train的跨模态知识。所提方法的性能明显优于所有基线方法和监督较弱的方法。本文转载自极市平台作者|CV开发者都爱看的仅用于学术分享,若侵权请联系删除欢迎关注公众号CV技术指南......
  • 1031. 两个非重叠子数组的最大和
    题目链接:1031.两个非重叠子数组的最大和方法:前缀和+哈兮解题思路考虑暴力解法,枚举以\(i\)结尾的长度为\(firstLen\)的子数组,求\([i+1,n-1]\)中长度为\(secondLen\)长度的子数组和的最大值,最后取两者和的最大值;优化:前缀和+哈兮假设\(firstLen\)在\(sec......
  • 对象专用流Demon03
    packagetest2;importjava.io.*;//对象专用流publicclassDemo04{publicstaticvoidmain(String[]args){FileOutputStreamfos=null;ObjectOutputStreamoos=null;try{fos=newFileOutputStream("H:\\Java2234\\Te......
  • mysql主从,django使用多数据库做读写分离
    mysql主从mysql主从搭建的目的1.读写分离2.单个实例并发量低,提高并发量3.只在主库写,读数据都去从库mysql主从原理步骤一:主库db的更新事件(update,insert,delete)被写道binlog步骤二:从库发起连接,连接到主库步骤三:此时主库创建一个binlogdumpthread线程,把binlog的内容发送到......