Go语言表达式
表达式表达的是一个计算过程,参与该计算过程的有数值、常量与变量、操作符(包括运算符)、函数等,表达式最终计算的结果一般是一个数值。简单地说,表达式就是通过一组计算获取某个结果值的算式。
1.1 最简单的表达式——单个数值
由于表达式最终计算的结果是一个数值,因此也可以反过来说,程序中代表一个数值的内容都可以看作表达式,单个数值也可以看作一个表达式,是一个没有运算操作的表达式。由于单个常量或变量也是用于存储数值的,所以单个常量或变量也可以算作一个表达式。
18 -26.08 0xFFEE "abcde" true false Pi a number1
1.2 操作符在表达式中的作用
通过组合数值和操作符,可以组成更复杂的表达式。
3+15
这是一个表达式,表示两个数字相加的计算过程。这个表达式中用到了一个加法操作符,可以看出该操作符的作用是将其前后两个数值进行加法计算后获得一个结果值,也就是通过数学上的 “求和” 计算获得结果值。
像加号这样需要前后两个数值参数与该计算操作的操作符叫作 "二元操作符"。Go 语言中除了二元操作符之外,还有"一元操作符",也就是只需要一个数值参与计算的操作符:
!true
典型的一元操作符还有表示正负的 "+" ,"-" 号,以及表示内存地址取值的 "&" 符号等。
-
+、-、*、/
分别对应数学中的加减乘除号。
-
==、!=、>、>=、<、<=
"==" 和 “!=” 分别是条件判断中判断两个数值是否相等还是不等的操作符,将返回一个布尔类型的结果 true 或 false。
-
%
百分号 "%" 作为操作符的时候作用是 "取模",也就是求一个数除以另一个数的余数,例如 5 对 3 取模用表达式表示是 5 % 3,其结果为 2。
-
&、|、^、&^
这几个符号作为两个数值之间的操作符时,其作用是让两个数进行二进制形式按位进行的 "与" "或" "异或" "与非" 操作。以按位 "与" 操作为例。
如果两个数字分别为 1 和 2,则表示按位 "与" 操作的表达式是 1 & 2。其他操作符类似。
-
>>、<<
">>" 和 "<<" 则是对一个数字进行二进制位的 "移位" 操作。所谓 "移位",指的是将各个二进制位的数字一同向某个方向移动的一个位置,移动后溢出的二进制位上的数字被丢弃,而空出来的那个位置会补充一个二进制的 0。
">>"代表左移,"<<"代表右移。移位操作符后面的数字表示移动几位。
-
&&、||、!
""&&" "||" "!" 操作符分别叫作 "逻辑与" "逻辑或" "逻辑非" 操作符。
"逻辑与" "逻辑或" 的作用是将其前后的两个布尔类型数值做 "与" 和 "或" 的操作,与 "按位与" 和 "按位或" 操作类似,但并非对二进制位进行操作。
"逻辑与"操作的含义是:如果两个布尔型数值都是true,则结果为true,否则为false。
"逻辑或"操作的含义是:如果两个布尔型数值至少有一个是ture,则结果为true,否则为false。
"逻辑非"操作的含义是:将一个布尔值进行取反操作,即如果是true,则变为false,如果是false则变为true。
1.3 函数在表达式中的作用
函数在表达式中的作用与操作符类似,甚至可以把操作符看做简化的函数。这是因为可以把操作符看作是接受 1 个或 2 个参数并返回 1 个数值的函数。
1.4 表达式的组合与计算的优先级
表达式通过组合可以称为更复杂的表达式
16-7*18
这是一个含有 3 个数值和 2 个操作符的表达式。计算机在计算表达式的时候有一定的优先级顺序,就像我们在数学算式中乘法的优先级高于加减法一样。这个算式在算计中将先计算 7 * 18,这个字表达式的值,再将结果与 16 进行减法运算。
计算机中的优先级顺序的规则如下:
- 函数优先级最高
- 其次是一元运算符
- 再次是二元操作符,二元操作符之间的运算优先级如下:
- *、/、%、<<、>>、&、&^ 等优先级最高;
- ==、!=、<、<=、>、>= 再次之
- &&;
- ||
- 相同优先级的操作符或函数,将按照从左到右的顺序依次进行计算。
- 表达式中可以通过圆括号改变计算的优先级,最里层嵌套的圆括号内的子表达式运算优先级是最高的,然后是较外层的圆括号,并如此逐级向外进行云算。
- 函数参数中如果有表达式,则每个参数独立进行计算(即仅将后传入函数作为参数,不作为函数外部的表达式成分)。
1.5 表达式中数据类型的一致性要求
在 Go 语言中,很多二元操作符要求参与该操作的两个数值类型一致:
package main import ( "fmt" ) func main() { fmt.Printf("%v", 15+25.6) a := 15 b := 25.6 fmt.Printf("%v", a+b) }
上面代码中,第一条 Printf 语句是正确的,第二天 Printf 是错误的。
这是因为对于第一个 Printf 语句中的表达式 15+25.6,Go 语言会自动将两个数字都认为是浮点数而进行加法操作。
而第二个表达式中的变量 a 在之前已经通过 := 操作符自动被认为是 int 类型的变量,而 b 则是 float64 类型,两者是不允许进行加法操作的。
如果一定要改变这种约束,例如要求计算一个整数与浮点数的相加结果,可以使用自定义函数的方式,但其内部的实质还是要经过类型转换变为同一类型再进行加法操作。