Go的变量类型、Go函数、Go的包、Go的流程控制、Switch关键字

GO的变量类型

1.普通类型

1.整形
int   int8   int16   int32   int64

int8 -27次方~27次方-1     ====》》  一个字节表示(8个比特位)
int16 -215次方~215次方-1
int32 同理
int64 同理

int 分机器,32位机器是int32  64位机器是int64


uint  uint8  uint16  uint32  uint64
因为不需要负的,所以扩容一倍

uint8 28次方-1
uint16 216次方 -1 

uint同理


浮点型:表示小数
float32   保留小数点后7位左右
float64   保留小数点后16位左右
不够准确的,带有末尾四舍五入


复数类型  实部和虚部,各自独立运算
complex64 
complex128


rune  byte
runeint32 的别名
byteuint8 的别名   


2.字符串

string

双引号  不能自动换行,要加换行符
反引号  带换行格式

单引号   放一个字符,对应的是ascci码的编码数字


3.布尔类型
只有
true 
false 

空值是false



2.常量

1.一旦定义,值固定了后续不能修改

const 关键字申明定义常量

================
2.作用域范围:

变量重复定义只要不在同一个范围内,可以搞,但是外部定义必须用完整定义或者类型推导
比如
var name string = "jack"
func main() {
	name = "rose"   # 优先用自己作用域的
	fmt.Println(name) 

}

3.同一时间定义多个常量,如果第二个常量不赋值,他的值就是第一个常量的值

3.iota的使用

​ 必须用const定义

​ 有啥用啊?能用来做枚举,但是目前还先不做了解枚举

const (
a = iota  
b          // 1
c         //  2
d         //  3
  
)

只要用了iota,下一行开始就会自增

===================

const (
    a = 10
    b
    c = 15
    d = iota             // d 值是3 
)

类似看索引位置,只要用了iota 就是值为索引值

Go的函数

1.普通函数

​ 注意,Go支持函数写在执行的后面,Python则不行的,因为一个是编译型,一个是解释型

1.无参无返回值
 就很简单的使用
    
2.有参数,无返回值
	需要指定参数类型!!!参数位置定死,关键字传参
func test(a, b int) {

	fmt.Println(a, b)
	
}

调用:
test(1,4)   # test(a=1,b=4)不行
3.有参数,有一个返回值
func test(a,b int) int {
    return a+b
}
res := test(1,5)
    fmt.Println(res)
    
    
4.有参数,有多个返回值
func test(a, b int) (int, int) {

	return a + b, a * b

}

调用:
res, res1 := test(1, 3)
fmt.Println(res)
fmt.Println(res1)

5.调用第四种的函数,不想要某个返回值
 '_' 这玩意是真正的空白!!
res, _ := test(1, 3)
fmt.Println(res)

2.函数高级

1.匿名函数
1.func (){
    ....
}()

加括号直接调用

2.赋值给一个变量--->函数是一种类型---》在go中,函数又称一等公民(可以赋值给变量的都叫一等公民),又叫头等函数,一等函数
func test4() {

	f := func() {
		fmt.Println("我是内层函数")
	}
	f()
}


3.函数的参数不同,是不同的类型
func test4() {

	var f func() = func() {
		fmt.Println("我是内层函数")

	}
	var f1 func(a int) = func(a int) {
		fmt.Println(a)
	}
	fmt.Printf("%T\n", f)
	fmt.Printf("%T", f1)
}

>>>
func()
func(int)    // 不同类型

2.返回值是函数
定义这样一个函数,需要传参一个函数进去,返回两个返回值
func test5(a func()) func(int, int) int {
	a()
	return func(x, y int) int {
		return x + y
	}
}

调用:
func main() {
	f := test5(func() {
		fmt.Println("我是被传入的函数")
	})
	res := f(11, 12)     # 结果是 23
	fmt.Println(res)
}
3.类型重命名——type
1.type Myint int 
	相当于创建了全新的一种类型,不能与不同类型的数据做运算,
2.type Myint = int 
	这个就是重命名,本质还是指向原来的类型

可以看作是深浅拷贝
	
4.可变长参数

​ Go中没有关键字参数,只有可变长

定义一个函数 ,...表示任意长度,可以指定一起的类型
func test6(a ...int) {
	fmt.Println(a)
	fmt.Printf("%T", a)
}

调用:
test6(1, 2, 3, 4, 5, 6, 6, 7, 8)

结果:
[1 2 3 4 5 6 6 7 8]
[]int            
Go中列表叫切片,切片又有很多类型,比如这种,int切片类型

5.defer 延迟调用
可以用来修饰GO语句,会延迟调用,并且以先进后出的原则,最先声明defer的GO语句最后执行

比如:

defer fmt.Println("你好~")
defer fmt.Println("你也好~")
fmt.Println("我本来是最后执行的")
 执行的结果是
    >>>
    我本来是最后执行的
	你也好~
	你好~
	>>>
 
如果涉及到引用,如果是内部引用外部,值按照defer执行时的算
如果是定义的时候就已经把外部某个值传进去,那值按defer执行前的算
比如:
var a = 100
defer func() {
    fmt.Println(a)
}()
a = 99

	该func直接引用a,延迟生效,生效时a已经是99
================================
var a = 100
defer func(i int) {
    fmt.Println(i)
}(a)
a = 99
	该func定义阶段就把a当实参传入,此时a已经被复制进去了,定死了,所以a=100

Go的包

​ go 的包分为:sdk内置包 、自定义包、第三方包

​ 包就是文件夹,这个文件夹下所有的go文件第一行都要声明包,建议就是包的名字,虽然可以自己定声明的名字

1.包的交互

​ 注意,包内部,大写开头,表示导出 变量,函数。。。

​ 同一个包下,名称空间共享,如果重新定义会冲突

​ 同一个文件夹下只能有一个包,意思就是该路径下不同go文件的包不能不一样

​ 一个文件夹下可以再创建新的包,各个文件夹只有层级关系无其他联系

​ 以上组成的模式叫go mod 模式,从1.11后都是这种模式,项目根路径下会有一个go.mod

我们在项目路径下创建一个包,创建一个go文件
比如 fun/happy.go

文件中写点东西
package ggo

var Wohh = 10

func Test(a, b int) int {
	return a + b
}


然后我们去根目录下的其他文件,带有main包的,因为main包才能作为执行文件
package main

import (
	"fmt"
	"go_day01/ggo"           # 会自动识别路径
)

func main() {
	res := ggo.Test(1, 4)
	fmt.Println(res)
	fmt.Println(ggo.Wohh)
}


​ 导入包可以重命名,重命名完成后以后直接用包名点即可

import (
	"fmt"
	xixixi "go_day01/ggo"
)

xixixi.Wohh

2.包的init

​ 可以重复定义

给ggo文件中加入init
func init() {
	fmt.Println("哇,我会自动执行")
}

func init() {
	fmt.Println("哇,我也会自动执行")
}

func init() {
	fmt.Println("哇,我绝对会自动执行")
}

==========================================
只要有main执行了导入这个包的操作,就会执行所有的init,类似python 的 __init__

3.光导入不使用

导入时做成空白 _
import _ "go_day01/ggo"
这样就可以避免go的只要导入必须使用的原则

但是注意,init一样会执行,因为你确实导入了

Go的gin框架

1.下载

官网地址
https://gin-gonic.com/zh-cn/docs/quickstart/

安装
go get -u github.com/gin-gonic/gin      // 要换下源才能快速下载

换源
GOPROXY=https://goproxy.cn,direct
可以局部换
	去go_land   File | Settings | Go | Go Modules 粘贴https://goproxy.cn,direct
或者全局改

2.简单使用

// 程序入口包
package main

// 导入gin框架
import "github.com/gin-gonic/gin"

func main() {
	// gin框架的默认实例
	r := gin.Default()

	// 加载templates目录下的所有HTML模板文件,以供后续渲染使用
	r.LoadHTMLGlob("templates/*")

	// GET请求处理函数,返回JSON数据
	r.GET("/", func(context *gin.Context) {
		context.JSON(200, gin.H{
			"code":    "100",
			"message": "成功",
		})
	})

	// GET请求处理函数,返回HTML模板页面
	r.GET("/index", func(context *gin.Context) {
		// 通过HTML渲染模板文件index.html,并且传入模板变量name和age
		context.HTML(200, "index.html", gin.H{
			"name": "jack",
			"age":  24,
		})
	})

	// 启动HTTP服务器,监听8080端口
	r.Run()
}

都是固定搭配,暂时听个响,然后启动这个文件file,访问浏览器8080端口即可

Go流程控制

1.if条件

固定格式:
注意else必须同行,不能换行下去

if 条件 {
...
} else if 条件 {
...
} else{
...
}

演示:
package main

import "fmt"

func main() {

	a := 200
	if a >= 100 {
		fmt.Println("厉害啊!")
	} else if a >= 150 && a <= 160 {
		fmt.Println("哇太厉害了!")
	} else {
		fmt.Println("啊哦")
	}

}

2.for循环

格式:
for 定义变量 ; 条件 ; 结果 {
    
}
三个都可以省略,但是一般起码有条件摆着,注意分号不能省,结构不能破坏(虽然编辑器会优化,但是习惯要好)
演示:
1.func main() {
	i := 0
	for ; i < 10; i++ {
		fmt.Println(i)
	}

}
2.结果放{}里面也可以的
func main() {
	i := 0
	for i < 10 {
		
		fmt.Println(i)
		i++
	}

}
3.都省,死循环
for {
    xxx
}


上面都是基于索引的循环
================================
这里是基于迭代的循环

func main() {
	s := "jack"
	for i, v := range s {   //range 按字符
		fmt.Println(i)
		fmt.Println(v)   // 这里拿的是字节数字,可以string转 	fmt.Println(string(v))
	}

}

break 和continue
和python一样的

Switch

​ 优雅的替换掉if 和 else

1.case   拿switch后面的值和case的值来比较,如果相同,执行相应的代码,也可以多条件,等于Or关联
func main() {
	a := 100
	switch a {
	case 90:                
		fmt.Println("我是90分")
	case 100:
		fmt.Println("我是一佰昏")

	}

}

2.default 相当于else
func main() {
	a := 101
	switch a {
	case 90:
		fmt.Println("我是90分")
	case 100:
		fmt.Println("我是一佰昏")
	default:
		fmt.Println("都不是哦")
	}

}


3.switch后无条件
func main() {
	a := 101
	switch {
	case a > 90 && a < 100:
		fmt.Println("我是优秀")
	case a > 100:
		fmt.Println("我是超棒")
	default:
		fmt.Println("都不是哦")
	}

}

break和Fallthrough

别的语言中switch 每个case下如果不写break 就会被触发

但是go 默认注入了break ,所以即使第一个条件达成了,第二第三个条件也不会触发


Fallthrough一加,如果该条件触发了,就会无条件执行下一个,就一个哦,不会多


func main() {
	a := 122
	switch {
	case a > 90 && a < 100:
		fmt.Println("我是优秀")
	case a > 100:
		fmt.Println("我是超棒")
		fallthrough
	case a < 60:
		fmt.Println("不行啊")
	default:
		fmt.Println("都不是哦")
	}

}

执行结果:

我是超棒
不行啊

注意

1.Go的那个文件,不是首行写了导入main包吗?如果新建的其他go文件,也是导入这个包,名称空间是共享的
2.Go的类型千奇百怪,函数也能作为类型
posted @   yiwufish  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示