golang的关键字
变量
var声明创建一个具体类型的变量,
- var name type = expression
Go是一种静态类型的语言,但是它仍然提供了一种在声明变量的同时省略数据类型声明的功能,类型和表达式可以省略一个,但是不能都省略;也就是golang支持类型推断
- var s string var b, f, s = true, 2, 3;
短变量声明
Golang中有两种创建变量的方法,如下所示:
-
使用var关键字
-
使用短变量声明运算符(:=)
使用短变量声明运算符的语法:
variable_name := 表达式 或 值 必须在声明后立即初始化变量,无需提及变量的类型, 右侧的表达式或值用于评估变量的类
声明仅具有块级作用域的局部变量
因其短小灵活,所以在局部变量的声明以及初始化中用的较多
:= 表示声明 而 = 表示赋值
只有在同一个词法语块中已经存在变量的情况下,短变量的行为才和赋值操作一样
go lang 中指针和clang 指针差不多
-
指针的声明和初始化可以在一行中完成。
var s *int = &a
*运算符 也称为解引用运算符,用于声明指针变量并访问存储在地址中的值。
&运算符 称为地址运算符,用于返回变量的地址或将变量的地址访问指针
new 函数
new
是内建函数,函数原型为
func new(Type) *Type
The new build-in function allocates memory(仅仅分配空间). The first argument is a type, not a value, and the value returned is a pointer to a newly allocated zero value of that type.内置函数 new
分配空间。传递给new
函数的是一个类型,不是一个值。返回值是 指向这个新分配的零值的指针。
多重赋值:
允许同时更新多个变量的值。在赋值之前,赋值语句右边的所有表达式将会先进行求值,然后再统一更新左边对应变量的值。
有些表达式会产生多个值,比如调用一个有多个返回值的函数。当这样一个函数调用出现在元组赋值右边的表达式中时(译注:右边不能再有其它表达式),左边变量的数目必须和右边一致
作用域:
声明语句的作用域对应的是一个源代码的文本区域;它是一个编译时的属性。一个变量的生命周期是指程序运行时变量存在的有效时间段,在此时间区域内它可以被程序的其他部分引用;是一个运行时的概念。
基本数据:
字符串
unicode是信源编码,对字符集数字化;所有的字符和码位(数字)建立了对应关系
utf8是信道编码,为更好的存储和传输。
常量
常量是一种表达式,其保证在编译的时候计算出表达式的值,每种常量的潜在类型都是基础类型:boolean、string或数字。
常量间的所有算术运算、逻辑运算和比较运算的结果也是常量,对常量的类型转换操作或以下函数调用都是返回常量结果:len、cap、real、imag、complex和unsafe.Sizeof
如果是批量声明的常量,除了第一个外其它的常量右边的初始化表达式都可以省略,如果省略初始化表达式则表示使用前面常量的初始化表达式写法,对应的常量类型也一样的。例如:
const ( a = 1 b c = 2 d ) fmt.Println(a, b, c, d) // "1 1 2 2"
常量声明可以使用iota常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不用每行都写一遍初始化表达式。在一个const声明语句中,在第一个声明的常量所在的行,iota将会被置为0,然后在每一个有常量声明的行加一
下面是来自time包的例子,它首先定义了一个Weekday命名类型,然后为一周的每天定义了一个常量,从周日0开始。在其它编程语言中,这种类型一般被称为枚举类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 | type Weekday int const ( Sunday Weekday = iota Monday Tuesday Wednesday Thursday Friday Saturday ) 周日将对应0,周一为1,如此等等。 |
数组
在数组字面值中,如果在数组的长度位置出现的是“...”省略号,则表示数组的长度是根据初始化值的个数来计算。因此,上面q数组的定义可以简化为
1 2 | q := [...] int {1, 2, 3} fmt.Printf( "%T\n" , q) // "[3]int" |
for 和 range
除了for Go 语言引入了另一个关键字 range
帮助我们快速遍历数组、切片、哈希表以及 Channel 等集合类型
- 初始化循环的
Ninit
; - 循环的继续条件
Left
; - 循环体结束时执行的
Right
; - 循环体
NBody
:
for Ninit; Left; Right { NBody }
hash := map[string]int{ "1": 1, "2": 2, "3": 3, } for k, v := range hash { println(k, v) }
分析遍历数组和切片清空元素的情况;
分析使用 for range a {} 遍历数组和切片,不关心索引和数据的情况;
分析使用 for i := range a {} 遍历数组和切片,只关心索引的情况;
分析使用 for i, elem := range a {} 遍历数组和切片,关心索引和数据的情况;
SELECT:
Go 语言中的 select
也能够让 Goroutine 同时等待多个 Channel 可读或者可写,在多个文件或者 Channel状态改变之前,select
会一直阻塞当前线程或者 Goroutine。
select
是与 switch
相似的控制结构,与 switch
不同的是,select
中虽然也有多个 case
,但是这些 case
中的表达式必须都是 Channel 的收发操作
C 语言的 select
系统调用可以同时监听多个文件描述符的可读或者可写的状态,Go 语言中的 select
也能够让 Goroutine 同时等待多个 Channel 可读或者可写,在多个文件或者 Channel状态改变之前,select
会一直阻塞当前线程或者 Goroutine
select
是与 switch
相似的控制结构,与 switch
不同的是,select
中虽然也有多个 case
,但是这些 case
中的表达式必须都是 Channel 的收发操作
当我们在 Go 语言中使用 select
控制结构时,会遇到两个现象:
select
能在 Channel 上进行非阻塞的收发操作;select
在遇到多个 Channel 同时响应时,会随机执行一种情况;
在通常情况下,select
语句会阻塞当前 Goroutine 并等待多个 Channel 中的一个达到可以收发的状态。但是如果 select
控制结构中包含 default
语句,那么这个 select
语句在执行时会遇到以下两种情况:
- 当存在可以收发的 Channel 时,直接处理该 Channel 对应的
case
; - 当不存在可以收发的 Channel 时,执行
default
中的语句;
Go 语言设计的这个现象很合理。select
的作用是同时监听多个 case
是否可以执行,如果多个 Channel 都不能执行,那么运行 default
也是理所当然的。
select
在遇到多个 <-ch
同时满足可读或者可写条件时会随机选择一个 case
执行其中的代码。
select 与 switch 原理很相似,但它的使用场景更特殊,学习了本篇文章,你需要知道如下几点区别:
-
select 只能用于 channel 的操作(写入/读出/关闭),而 switch 则更通用一些;
-
select 的 case 是随机的,而 switch 里的 case 是顺序执行;
-
select 要注意避免出现死锁,同时也可以自行实现超时机制;
-
select 里没有类似 switch 里的 fallthrough 的用法;
-
select 不能像 switch 一样接函数或其他表达式。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!