运算符

运算符介绍

运算符用于在程序运行时执行数学或逻辑运算,Go 语言内置的运算符有:

  • 一元运算符
    • +一元加法
    • -负数
  • 二元运算符

    • 算术运算符

    • 位运算符

    • 逻辑运算符

    • 比较运算符

Go语言中所有的二元运算符共有五种优先级,如下所示,它们按照优先级递减的顺序的排列:

优先级 运算符
5 * / % << >> & &^
4 + – | ^
3 == != < <= > >=
2 &&
1 ||

在同一个优先级,使用左优先结合规则,但是使用括号可以提升优先级,所以建议使用括号明确优先顺序。

一、 一元运算符

一元的加法和减法运算符 描述
+ 一元加法 (无效果)
负数

对于整数、浮点数和复数,+x就是x,-x则是x 的负数。例如+(-8)得-8

一元指针运算符 描述 实例
& 返回变量存储地址 &a; 将给出变量的实际地址。
* 指针变量。 *a; 是一个指针变量

二、 二元运算符

2.1、算数运算符

运算符 描述
+ 相加
相减
* 相乘
/ 相除
% 求余/取模

注意:

  • 1、算术运算符+、-、*/可以在整数、浮点数和复数之间混用,但是取模运算符%仅用于整数间的运算

    fmt.Println(3 % 2) // 1
    fmt.Println(3.1 % 2) // 报错:operator % not defined on untyped float
  • 2、在Go语言中,%取模运算符的符号和被取模数的符号总是一致的,因此-5%3-5%-3结果都是-2。

    // 可以这做
    -(-5 % -3)
  • 3、除法运算符/的行为则依赖于操作数是否为全为整数,例如

    fmt.Println(8.0 / 5.0) // 结果为1.6
    fmt.Println(8 / 5.0)  // 结果为1.6
    fmt.Println(8.0 / 5) // 结果为1.6
    
    fmt.Println(8 / 5)  // 结果为1,因为整数除法会向着0方向截断余数。
  • 4、因为除法运算符/会根据操作数的类型生成对应类型的结果,所以不同写法的常量除法表达式可能对应不同的结果:

    var f float64 = 212
    fmt.Println((f - 32) * 5 / 9)     // "100"; (f - 32) * 5 is a float64
    fmt.Println(5 / 9 * (f - 32))     // "0";   5/9 is an untyped integer, 结果为0
    fmt.Println(5.0 / 9.0 * (f - 32)) // "100"; 5.0/9.0 is an untyped float
  • 5、针对一个算术运算的结果,不管是有符号还是无符号的,如果需要更多的bit位才能正确表示的话,就说明计算结果是溢出了,而超出的高位的bit位部分将被丢弃,也就是说如果原始的数值是有符号类型,而且最左边的bit为是1的话,那么最终结果就可能是负的,例如int8的例子:

    var u uint8 = 255
    fmt.Println(u, u+1, u*u) // "255 0 1"
    
    var i int8 = 127
    fmt.Println(i, i+1, i*i) // "127 -128 1"

    ???为何出现128呢,egon来先扫一下盲,估计会扫死99%的人

    问:8位二进制数可以表示的数值范围是多少,99%的人张口就来:-128~127
    
    ​ ok,8位二进制数,最高位需要用来表示符号,那么剩下的7位用来表示数值
    
    ​ 于是,最大数为1111 1111=>+127,最小0111 1111=>-127,卧槽,得出的结论是8位二进制数可以表示的数值范围是-127到+127,傻逼了吧你,哈哈哈
    
    ​ 灵魂拷问:-128到底怎么来的???
    
    ​  真相是这样的:
     8位二进制数用7位表示数值,那么7位2进制数000 0000的值为0
     那么,它前面加上符号位0,还表示0吧?
     那好,如果它前面加上1呢,仍然表示0?这不是重复了么?
     一个0,怎么用两个值来表示呢!!!
     所以1000 0000就表示-128啦,
  • 6、字符串也可以使用+运算符

    其中+操作符将两个字符串链接构造一个新字符串:

    fmt.Println("goodbye" + s[5:]) // "goodbye, world"

    字符串可以用==和<进行比较;比较通过逐个字节比较完成的,因此比较的结果是字符串自然编码的顺序。

    字符串的值是不可变的:一个字符串包含的字节序列永远不会被改变,当然我们也可以给一个字符串变量分配一个新字符串值。可以像下面这样将一个字符串追加到另一个字符串:

    s := "left foot"
    t := s
    s += ", right foot"

    这并不会导致原始的字符串值被改变,但是变量s将因为+=语句持有一个新的字符串值,但是t依然是包含原先的字符串值。

    fmt.Println(s) // "left foot, right foot"
    fmt.Println(t) // "left foot"

2.2、位运算符

位运算符对整数在内存中的二进制位进行操作(详解附录:位运算)

运算符 描述 实例
<< 左移,左移n位就是乘以2的n次方。 “a<<b”是把a的各二进位全部左移b位,高位丢弃,低位补0。 A << 2 结果为 240 ,二进制为 1111 0000
>> 右移,右移n位就是除以2的n次方。 “a>>b”是把a的各二进位全部右移b位。 A >> 2 结果为 15 ,二进制为 0000 1111
& 位运算AND,参与运算的两数各对应的二进位相与。 (两位均为1才为1) (A & B) 结果为 12, 二进制为 0000 1100
| 位运算OR,参与运算的两数各对应的二进位相或。 (两位有一个为1就为1) (A | B) 结果为 61, 二进制为 0011 1101
^ 位运算XOR,参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 (两位不一样则为1) (A ^ B) 结果为 49, 二进制为 0011 0001
&^ 位清空 (AND NOT)

2.3、赋值运算符

联系管理员微信tutu19192010,注册账号

上一篇
下一篇
Copyright © 2022 Egon的技术星球 egonlin.com 版权所有 帮助IT小伙伴学到真正的技术