表达式
聽聽1.聽关键字 聽聽2.聽运算符 聽聽3.聽初始化
关键字
聽聽聽聽聽聽聽聽关键字是指被编程语言保留而不让编程人员作为标志符使用的字符序列。因此,关键字也称为保留字, 每种编程语言都有自己的关键字,从使用的角度看,我们可以把Go语言的25个关键字分为如下三类:
1.聽用于程序声明聽聽 2.聽用于程序实体声明和定义 3.聽用于程序流程控制的关键字
类别 | 关键字 |
---|---|
程序声明 | import, package |
实体声明和定义 | var,const,type,struct,func,interface,map,chan |
流程控制 | if,else,switch,case,fallthrough,default,for,range,continue,break,go,select,defer,goto,return |
运算符
聽聽聽聽聽聽聽聽运算符就是用于执行特定计算或逻辑操作的符号。 Go语言中全部运算符、分隔符以及其他特殊符号见下表:
+聽聽聽聽&聽聽聽聽聽+=聽聽聽聽&=聽聽聽聽聽&&聽聽聽聽==聽聽聽聽!=聽聽聽聽(聽聽聽聽) -聽聽聽聽|聽聽聽聽聽-=聽聽聽聽|=聽聽聽聽聽||聽聽聽聽<聽聽聽聽聽<=聽聽聽聽[聽聽聽聽] *聽聽聽聽^聽聽聽聽聽*=聽聽聽聽^=聽聽聽聽聽<-聽聽聽聽>聽聽聽聽聽>=聽聽聽聽{聽聽聽聽} /聽聽聽聽<<聽聽聽聽/=聽聽聽聽<<=聽聽聽聽++聽聽聽聽=聽聽聽聽聽:=聽聽聽聽,聽聽聽聽; %聽聽聽聽>>聽聽聽聽%=聽聽聽聽>>=聽聽聽聽--聽聽聽聽!聽聽聽聽聽...聽聽聽.聽聽聽聽: 聽聽聽聽聽&^聽聽聽聽&^=
运算符分类:
1.聽算术运算符 2.聽关系运算符 3.聽逻辑运算符 4.聽位运算符 5.聽赋值运算符 6.聽其他运算符
算术运算符
下面为Go语言的算术运算符,假定A值为10,B值为20
运算符 | 描述 | 实例 |
---|---|---|
A+B | 加 | A + B 输出结果 30 |
A-B | 减 | A - B 输出结果 -10 |
A*B | 乘 | A * B 输出结果 200 |
A/B | 除 | B / A 输出结果 2 |
B%A | 求余 | B % A 输出结果 0 |
A++ | 自增 | A++ 输出结果 11 |
A-- | 自减 | A-- 输出结果 9 |
关系运算符
下面为Go语言的关系运算符,假定A值为10,B值为20:
运算符 | 描述 | 实例 |
---|---|---|
A==B | 检查两个值是否相等,如果相等返回 True 否则返回 False | (A == B) 为 False |
A!=B | 检查两个值是否不相等,如果不相等返回 True 否则返回 False | (A != B) 为 True |
A>B | 检查左边值是否大于右边值,如果是返回 True 否则返回 False | (A > B) 为 False |
A<B | 检查左边值是否小于右边值,如果是返回 True 否则返回 False | (A < B) 为 True |
A>=B | 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False | (A >= B) 为 False |
A<=B | 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False | (A <= B) 为 True |
逻辑运算符
下表列出了所有Go语言的逻辑运算符。假定 A 值为 True,B 值为 False
运算符 | 描述 | 实例 |
---|---|---|
A&&B | 逻辑AND运算符.如果两边的操作数都是True,则条件True,否则为False | (A && B) 为 False |
A||B | 逻辑OR运算符.如果两边的操作数有一个True,则条件True,否则为False | (A || B) 为 True |
!(A && B) | 逻辑NOT运算符.如果条件为True,则逻辑NOT条件False,否则为True | !(A && B) 为 True |
位运算符
下表列出了所有Go语言的位运算符。假定 A 值为 0101,B 值为 0011,C值为1,D值为8
运算符 | 描述 | 实例 |
---|---|---|
A&B | 按位与运算,两边都为1结果就为1 | 0101 & 0011 = 0001 |
A|B | 按位或运算,两边至少有一个为1结果就为1 | 0101 | 0011 = 0111 |
A^B | 按位亦或运算,两边只有一个为1结果就为1 | 0101 | 0011 = 0110 |
^A | 按位取反运算 | ^0111 = 1000 |
A&^B | 按位清除运算 | 0101 &^ 0110 = 0001 |
C<<2 | 位左移运算 | 1<<2 = 4 |
D>>2 | 位右移运算 | 8>>2 = 2 |
赋值运算符
下表列出了所有Go语言的赋值运算符
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符 | C = A + B 将 A + B 表达式结果赋值给 C |
+= | 相加后再赋值 | C += A 等于 C = C + A |
-= | 相减后再赋值 | C -= A 等于 C = C - A |
*= | 相乘后再赋值 | C聽= A 等于 C = C聽A |
/= | 相除后再赋值 | C /= A 等于 C = C / A |
%= | 求余后再赋值 | C %= A 等于 C = C % A |
<<= | 左移赋值 | C <<= 2 等于 C = C << 2 |
>>= | 右移赋值 | C >>= 2 等于 C = C >> 2 |
&= | 位逻辑与赋值 | C &= 2 等于 C = C & 2 |
|= | 位逻辑或赋值 | C |= 2 等于 C = C |2 |
^= | 位逻辑异或赋值 | C ^= 2 等于 C = C ^ 2 |
其他运算符
下表列出了Go语言的其他运算符
运算符 | 描述 | 实例 |
---|---|---|
& | 取址运算符 | &a 将给出变量a的实际地址 |
* | 指针运算符 | *a 将给出指针变量a所指向的值 |
<- | 接收运算符 | x,ok := <-ch,表示从channel中接收数据 |
:= | 短变量声明符 | var x = 100可以写成 x:= 100 |
优先级
当一个表达式中包含多个运算符时,就涉及到了运算符的运算优先级,在Go语言中,一元运算符拥有最高优先级,下表列出了Go语言的 二元运算符优先级,从高到低:
优先级|聽运算符聽聽 聽聽5聽聽|聽*聽聽聽/聽聽聽%聽聽聽<<聽聽聽>>聽聽聽&聽聽聽&^ 聽聽4聽聽|聽+聽聽聽-聽聽聽|聽聽聽^ 聽聽3聽聽|聽==聽聽!=聽聽聽<聽聽聽<=聽聽聽>聽聽聽>= 聽聽2聽聽|聽&& 聽聽1聽聽|聽||
另外下面几点是日常开发中需要注意的:
可以通过使用括号来临时提升某个表达式的整体运算优先级
位操作
除了位操作外,操作数类型必须相同,如果其中一个是无显示类型声明的常量,那么该常量操作数就会 做自动转型,比如:
const聽v聽=聽20 var聽a聽byte聽=聽10 b聽:=聽a聽+聽v聽聽//聽v常量被自动转型为byte/uint8聽类型 const聽f聽float32聽=聽1.2 d聽:=聽f聽+聽v聽聽//聽v常量被自动转型为float32聽类型
位移右操作数必须是无符号数或可以转换的无显示类型常量,比如:
b聽:=聽2 x聽聽:=聽1聽<<聽b聽聽聽聽//b聽是有符号int类型变量,这样是无效的
如果是非常量位移表达式,那么会优先将无显示类型的常量左操作数转型,比如:
a聽:=聽1.0聽<<聽3聽聽//常量表达式 c聽:=聽1.3聽<<聽3聽//constant聽1.3聽truncated聽to聽integer var聽s聽uint聽=聽3 b聽:=聽1.0聽<<聽s聽//invalid聽operation:聽1聽<<聽s聽(shift聽of聽type聽float64) var聽i聽int32聽=聽1.0聽<<聽s聽//自动将1.0聽转换为int32
自增/自减
不能用于表达式,只能作为独立语句,比如:
a聽:=聽1 ++a聽//syntax聽error:聽unexpected聽++聽聽不能前置 if聽(a++)聽>聽1{聽//syntax聽error:聽unexpected聽++聽不能作为表达式 } a++ p聽:=聽&a *p++聽聽//*p++相当于(*p)++
指针
不能将指针与内存地址混位一体,内存地址是在内存中每个字节单元的唯一编号,而指针就相当于是用来保存地址的整型变量,自身也会占用内存空间。 比如上例中的p := &a
a聽:=1聽p聽:=聽&a fmt.Println(&a,a) fmt.Println(&p,p,*p) 输出:0x1040e0f8聽10x1040a120聽0x1040e0f8聽1
并不是所有的对象都能进行取址操作,比如:
m聽:=聽map[string]string{"hello":"go"} println(&m["hello"])聽聽聽聽//cannot聽take聽the聽address聽of聽m["hello"]
指针类型不能做加减法和类型转换,支持相等运算符
a聽:=聽10 p聽:=聽&a p++聽聽聽//invalid聽operation:聽p++聽(non-numeric聽type聽*int) p2聽:=聽&a println(p聽==聽p2)聽//支持相等运算符
零长度对象(声明但未赋值)的对象地址是否相等和具体实现有关,Go编译器会根据其实现的不同,进行不同的优化, 从正确性的角度看,用户是不用关心内存在哪里(堆栈)分配的,不过肯定不为nil,比如:
var聽a,b聽int聽//虽然长度为0,但是对象是合法存在的,就拥有合法内存地址,不会为nil println(&a聽,聽&b) println(&a聽==聽&b,&a聽==聽nil) 输出: 聽聽聽聽0x10429f64聽0x10429f60 聽聽聽聽false聽false var聽a,b聽struct{} println(&a聽,聽&b) println(&a聽==聽&b,&a聽==聽nil) 输出: 聽聽聽聽0x10429f65聽0x10429f65 聽聽聽聽true聽false
指针没有专门指向成员的"->"运算符, 统一使用".",比如:
a聽:=聽struct{ 聽聽聽聽x聽int 聽聽}{} 聽聽a.x聽=聽10聽聽//相当于a->x 聽聽p聽:=聽&a 聽聽p.x聽+=聽10聽聽聽//相当于p->x 聽聽println(p.x)
初始化
聽 聽基本变量的初始化前面已经提到了字面量,在Go语言中,对复合类型变量(数组、切片、字典、结构体) 的初始化是有一些语法限制的,但对基本变量的初始化没有这些限制,比如:
1.聽初始化表达式必须含有类型标签 2.聽左花括号不能另起一行,必须在类型尾部 3.聽多成员初始值必须用逗号","分隔 4.聽允许多行编写,但是每行必须以逗号","或右花括号结束
示例如下:
type聽stu聽struct{ 聽聽聽聽name聽string 聽聽聽聽age聽int } b聽:=聽stu{聽聽聽聽 聽聽聽聽"zhang", 聽聽聽聽20聽聽聽聽聽聽聽//unexpected聽semicolon聽or聽newline,聽expecting聽comma聽or聽},须以逗号或右花括号结束 } b聽:=聽stu {聽聽聽//syntax聽error:聽unexpected聽},聽expecting聽expression,左花括号不能另起一行 聽聽聽聽"zhang", 聽聽聽聽20, } var聽data聽stu聽=聽{"wang",20}聽//syntax聽error:聽missing聽operand,初始化表达式必须含有类型标签
借鉴: 雨痕<GO学习笔记>
讨论微信: 675020908
本文出自 “博学于文,约之于礼” 博客,转载请与作者联系!
有疑问加站长微信联系(非本文作者)