操作符和标点符号

操作符和标点符号(48个)

1
2
3
4
5
6
+    &     +=    &=     &&    ==    !=    (    )
-    |     -=    |=     ||    <     <=    [    ]
*    ^     *=    ^=     <-    >     >=    {    }
/    <<    /=    <<=    ++    =     :=    ,    ;
%    >>    %=    >>=    --    !     ...   .    :
     &^          &^=          ~

原码、反码、补码

​ 正数的反码和补码与原码相同;负数的反码是除了符号位外按位取反,负数的补码是在反码基础上加1。

​ 以int8为例,看看其正整数、0、负整数的原码和补码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
	"fmt"
	"math"
)

func main() {
	z := int8(127)

	fmt.Printf("数        原码         反码         补码\n")
	for z > -128 || z == -128 {
		var f int8
		f = z
		if z < 0 {
			f = int8((^uint8(math.Abs(float64(z)))) | 0b10000000)
		}
		fmt.Printf("%3d | %#08b | %#08b | %#08b\n", z, z, f, uint8(z))
		if z == -128 {
			break
		}
		z--
	}
}
数        原码         反码         补码
127 | 0b01111111 | 0b01111111 | 0b01111111
126 | 0b01111110 | 0b01111110 | 0b01111110
125 | 0b01111101 | 0b01111101 | 0b01111101
124 | 0b01111100 | 0b01111100 | 0b01111100
123 | 0b01111011 | 0b01111011 | 0b01111011
122 | 0b01111010 | 0b01111010 | 0b01111010
121 | 0b01111001 | 0b01111001 | 0b01111001
120 | 0b01111000 | 0b01111000 | 0b01111000
119 | 0b01110111 | 0b01110111 | 0b01110111
118 | 0b01110110 | 0b01110110 | 0b01110110
117 | 0b01110101 | 0b01110101 | 0b01110101
116 | 0b01110100 | 0b01110100 | 0b01110100
115 | 0b01110011 | 0b01110011 | 0b01110011
114 | 0b01110010 | 0b01110010 | 0b01110010
113 | 0b01110001 | 0b01110001 | 0b01110001
112 | 0b01110000 | 0b01110000 | 0b01110000
111 | 0b01101111 | 0b01101111 | 0b01101111
110 | 0b01101110 | 0b01101110 | 0b01101110
109 | 0b01101101 | 0b01101101 | 0b01101101
108 | 0b01101100 | 0b01101100 | 0b01101100
107 | 0b01101011 | 0b01101011 | 0b01101011
106 | 0b01101010 | 0b01101010 | 0b01101010
105 | 0b01101001 | 0b01101001 | 0b01101001
104 | 0b01101000 | 0b01101000 | 0b01101000
103 | 0b01100111 | 0b01100111 | 0b01100111
102 | 0b01100110 | 0b01100110 | 0b01100110
101 | 0b01100101 | 0b01100101 | 0b01100101
100 | 0b01100100 | 0b01100100 | 0b01100100
 99 | 0b01100011 | 0b01100011 | 0b01100011
 98 | 0b01100010 | 0b01100010 | 0b01100010
 97 | 0b01100001 | 0b01100001 | 0b01100001
 96 | 0b01100000 | 0b01100000 | 0b01100000
 95 | 0b01011111 | 0b01011111 | 0b01011111
 94 | 0b01011110 | 0b01011110 | 0b01011110
 93 | 0b01011101 | 0b01011101 | 0b01011101
 92 | 0b01011100 | 0b01011100 | 0b01011100
 91 | 0b01011011 | 0b01011011 | 0b01011011
 90 | 0b01011010 | 0b01011010 | 0b01011010
 89 | 0b01011001 | 0b01011001 | 0b01011001
 88 | 0b01011000 | 0b01011000 | 0b01011000
 87 | 0b01010111 | 0b01010111 | 0b01010111
 86 | 0b01010110 | 0b01010110 | 0b01010110
 85 | 0b01010101 | 0b01010101 | 0b01010101
 84 | 0b01010100 | 0b01010100 | 0b01010100
 83 | 0b01010011 | 0b01010011 | 0b01010011
 82 | 0b01010010 | 0b01010010 | 0b01010010
 81 | 0b01010001 | 0b01010001 | 0b01010001
 80 | 0b01010000 | 0b01010000 | 0b01010000
 79 | 0b01001111 | 0b01001111 | 0b01001111
 78 | 0b01001110 | 0b01001110 | 0b01001110
 77 | 0b01001101 | 0b01001101 | 0b01001101
 76 | 0b01001100 | 0b01001100 | 0b01001100
 75 | 0b01001011 | 0b01001011 | 0b01001011
 74 | 0b01001010 | 0b01001010 | 0b01001010
 73 | 0b01001001 | 0b01001001 | 0b01001001
 72 | 0b01001000 | 0b01001000 | 0b01001000
 71 | 0b01000111 | 0b01000111 | 0b01000111
 70 | 0b01000110 | 0b01000110 | 0b01000110
 69 | 0b01000101 | 0b01000101 | 0b01000101
 68 | 0b01000100 | 0b01000100 | 0b01000100
 67 | 0b01000011 | 0b01000011 | 0b01000011
 66 | 0b01000010 | 0b01000010 | 0b01000010
 65 | 0b01000001 | 0b01000001 | 0b01000001
 64 | 0b01000000 | 0b01000000 | 0b01000000
 63 | 0b00111111 | 0b00111111 | 0b00111111
 62 | 0b00111110 | 0b00111110 | 0b00111110
 61 | 0b00111101 | 0b00111101 | 0b00111101
 60 | 0b00111100 | 0b00111100 | 0b00111100
 59 | 0b00111011 | 0b00111011 | 0b00111011
 58 | 0b00111010 | 0b00111010 | 0b00111010
 57 | 0b00111001 | 0b00111001 | 0b00111001
 56 | 0b00111000 | 0b00111000 | 0b00111000
 55 | 0b00110111 | 0b00110111 | 0b00110111
 54 | 0b00110110 | 0b00110110 | 0b00110110
 53 | 0b00110101 | 0b00110101 | 0b00110101
 52 | 0b00110100 | 0b00110100 | 0b00110100
 51 | 0b00110011 | 0b00110011 | 0b00110011
 50 | 0b00110010 | 0b00110010 | 0b00110010
 49 | 0b00110001 | 0b00110001 | 0b00110001
 48 | 0b00110000 | 0b00110000 | 0b00110000
 47 | 0b00101111 | 0b00101111 | 0b00101111
 46 | 0b00101110 | 0b00101110 | 0b00101110
 45 | 0b00101101 | 0b00101101 | 0b00101101
 44 | 0b00101100 | 0b00101100 | 0b00101100
 43 | 0b00101011 | 0b00101011 | 0b00101011
 42 | 0b00101010 | 0b00101010 | 0b00101010
 41 | 0b00101001 | 0b00101001 | 0b00101001
 40 | 0b00101000 | 0b00101000 | 0b00101000
 39 | 0b00100111 | 0b00100111 | 0b00100111
 38 | 0b00100110 | 0b00100110 | 0b00100110
 37 | 0b00100101 | 0b00100101 | 0b00100101
 36 | 0b00100100 | 0b00100100 | 0b00100100
 35 | 0b00100011 | 0b00100011 | 0b00100011
 34 | 0b00100010 | 0b00100010 | 0b00100010
 33 | 0b00100001 | 0b00100001 | 0b00100001
 32 | 0b00100000 | 0b00100000 | 0b00100000
 31 | 0b00011111 | 0b00011111 | 0b00011111
 30 | 0b00011110 | 0b00011110 | 0b00011110
 29 | 0b00011101 | 0b00011101 | 0b00011101
 28 | 0b00011100 | 0b00011100 | 0b00011100
 27 | 0b00011011 | 0b00011011 | 0b00011011
 26 | 0b00011010 | 0b00011010 | 0b00011010
 25 | 0b00011001 | 0b00011001 | 0b00011001
 24 | 0b00011000 | 0b00011000 | 0b00011000
 23 | 0b00010111 | 0b00010111 | 0b00010111
 22 | 0b00010110 | 0b00010110 | 0b00010110
 21 | 0b00010101 | 0b00010101 | 0b00010101
 20 | 0b00010100 | 0b00010100 | 0b00010100
 19 | 0b00010011 | 0b00010011 | 0b00010011
 18 | 0b00010010 | 0b00010010 | 0b00010010
 17 | 0b00010001 | 0b00010001 | 0b00010001
 16 | 0b00010000 | 0b00010000 | 0b00010000
 15 | 0b00001111 | 0b00001111 | 0b00001111
 14 | 0b00001110 | 0b00001110 | 0b00001110
 13 | 0b00001101 | 0b00001101 | 0b00001101
 12 | 0b00001100 | 0b00001100 | 0b00001100
 11 | 0b00001011 | 0b00001011 | 0b00001011
 10 | 0b00001010 | 0b00001010 | 0b00001010
  9 | 0b00001001 | 0b00001001 | 0b00001001
  8 | 0b00001000 | 0b00001000 | 0b00001000
  7 | 0b00000111 | 0b00000111 | 0b00000111
  6 | 0b00000110 | 0b00000110 | 0b00000110
  5 | 0b00000101 | 0b00000101 | 0b00000101
  4 | 0b00000100 | 0b00000100 | 0b00000100
  3 | 0b00000011 | 0b00000011 | 0b00000011
  2 | 0b00000010 | 0b00000010 | 0b00000010
  1 | 0b00000001 | 0b00000001 | 0b00000001
  0 | 0b00000000 | 0b00000000 | 0b00000000
 -1 | -0b0000001 | -0b0000010 | 0b11111111
 -2 | -0b0000010 | -0b0000011 | 0b11111110
 -3 | -0b0000011 | -0b0000100 | 0b11111101
 -4 | -0b0000100 | -0b0000101 | 0b11111100
 -5 | -0b0000101 | -0b0000110 | 0b11111011
 -6 | -0b0000110 | -0b0000111 | 0b11111010
 -7 | -0b0000111 | -0b0001000 | 0b11111001
 -8 | -0b0001000 | -0b0001001 | 0b11111000
 -9 | -0b0001001 | -0b0001010 | 0b11110111
-10 | -0b0001010 | -0b0001011 | 0b11110110
-11 | -0b0001011 | -0b0001100 | 0b11110101
-12 | -0b0001100 | -0b0001101 | 0b11110100
-13 | -0b0001101 | -0b0001110 | 0b11110011
-14 | -0b0001110 | -0b0001111 | 0b11110010
-15 | -0b0001111 | -0b0010000 | 0b11110001
-16 | -0b0010000 | -0b0010001 | 0b11110000
-17 | -0b0010001 | -0b0010010 | 0b11101111
-18 | -0b0010010 | -0b0010011 | 0b11101110
-19 | -0b0010011 | -0b0010100 | 0b11101101
-20 | -0b0010100 | -0b0010101 | 0b11101100
-21 | -0b0010101 | -0b0010110 | 0b11101011
-22 | -0b0010110 | -0b0010111 | 0b11101010
-23 | -0b0010111 | -0b0011000 | 0b11101001
-24 | -0b0011000 | -0b0011001 | 0b11101000
-25 | -0b0011001 | -0b0011010 | 0b11100111
-26 | -0b0011010 | -0b0011011 | 0b11100110
-27 | -0b0011011 | -0b0011100 | 0b11100101
-28 | -0b0011100 | -0b0011101 | 0b11100100
-29 | -0b0011101 | -0b0011110 | 0b11100011
-30 | -0b0011110 | -0b0011111 | 0b11100010
-31 | -0b0011111 | -0b0100000 | 0b11100001
-32 | -0b0100000 | -0b0100001 | 0b11100000
-33 | -0b0100001 | -0b0100010 | 0b11011111
-34 | -0b0100010 | -0b0100011 | 0b11011110
-35 | -0b0100011 | -0b0100100 | 0b11011101
-36 | -0b0100100 | -0b0100101 | 0b11011100
-37 | -0b0100101 | -0b0100110 | 0b11011011
-38 | -0b0100110 | -0b0100111 | 0b11011010
-39 | -0b0100111 | -0b0101000 | 0b11011001
-40 | -0b0101000 | -0b0101001 | 0b11011000
-41 | -0b0101001 | -0b0101010 | 0b11010111
-42 | -0b0101010 | -0b0101011 | 0b11010110
-43 | -0b0101011 | -0b0101100 | 0b11010101
-44 | -0b0101100 | -0b0101101 | 0b11010100
-45 | -0b0101101 | -0b0101110 | 0b11010011
-46 | -0b0101110 | -0b0101111 | 0b11010010
-47 | -0b0101111 | -0b0110000 | 0b11010001
-48 | -0b0110000 | -0b0110001 | 0b11010000
-49 | -0b0110001 | -0b0110010 | 0b11001111
-50 | -0b0110010 | -0b0110011 | 0b11001110
-51 | -0b0110011 | -0b0110100 | 0b11001101
-52 | -0b0110100 | -0b0110101 | 0b11001100
-53 | -0b0110101 | -0b0110110 | 0b11001011
-54 | -0b0110110 | -0b0110111 | 0b11001010
-55 | -0b0110111 | -0b0111000 | 0b11001001
-56 | -0b0111000 | -0b0111001 | 0b11001000
-57 | -0b0111001 | -0b0111010 | 0b11000111
-58 | -0b0111010 | -0b0111011 | 0b11000110
-59 | -0b0111011 | -0b0111100 | 0b11000101
-60 | -0b0111100 | -0b0111101 | 0b11000100
-61 | -0b0111101 | -0b0111110 | 0b11000011
-62 | -0b0111110 | -0b0111111 | 0b11000010
-63 | -0b0111111 | -0b1000000 | 0b11000001
-64 | -0b1000000 | -0b1000001 | 0b11000000
-65 | -0b1000001 | -0b1000010 | 0b10111111
-66 | -0b1000010 | -0b1000011 | 0b10111110
-67 | -0b1000011 | -0b1000100 | 0b10111101
-68 | -0b1000100 | -0b1000101 | 0b10111100
-69 | -0b1000101 | -0b1000110 | 0b10111011
-70 | -0b1000110 | -0b1000111 | 0b10111010
-71 | -0b1000111 | -0b1001000 | 0b10111001
-72 | -0b1001000 | -0b1001001 | 0b10111000
-73 | -0b1001001 | -0b1001010 | 0b10110111
-74 | -0b1001010 | -0b1001011 | 0b10110110
-75 | -0b1001011 | -0b1001100 | 0b10110101
-76 | -0b1001100 | -0b1001101 | 0b10110100
-77 | -0b1001101 | -0b1001110 | 0b10110011
-78 | -0b1001110 | -0b1001111 | 0b10110010
-79 | -0b1001111 | -0b1010000 | 0b10110001
-80 | -0b1010000 | -0b1010001 | 0b10110000
-81 | -0b1010001 | -0b1010010 | 0b10101111
-82 | -0b1010010 | -0b1010011 | 0b10101110
-83 | -0b1010011 | -0b1010100 | 0b10101101
-84 | -0b1010100 | -0b1010101 | 0b10101100
-85 | -0b1010101 | -0b1010110 | 0b10101011
-86 | -0b1010110 | -0b1010111 | 0b10101010
-87 | -0b1010111 | -0b1011000 | 0b10101001
-88 | -0b1011000 | -0b1011001 | 0b10101000
-89 | -0b1011001 | -0b1011010 | 0b10100111
-90 | -0b1011010 | -0b1011011 | 0b10100110
-91 | -0b1011011 | -0b1011100 | 0b10100101
-92 | -0b1011100 | -0b1011101 | 0b10100100
-93 | -0b1011101 | -0b1011110 | 0b10100011
-94 | -0b1011110 | -0b1011111 | 0b10100010
-95 | -0b1011111 | -0b1100000 | 0b10100001
-96 | -0b1100000 | -0b1100001 | 0b10100000
-97 | -0b1100001 | -0b1100010 | 0b10011111
-98 | -0b1100010 | -0b1100011 | 0b10011110
-99 | -0b1100011 | -0b1100100 | 0b10011101
-100 | -0b1100100 | -0b1100101 | 0b10011100
-101 | -0b1100101 | -0b1100110 | 0b10011011
-102 | -0b1100110 | -0b1100111 | 0b10011010
-103 | -0b1100111 | -0b1101000 | 0b10011001
-104 | -0b1101000 | -0b1101001 | 0b10011000
-105 | -0b1101001 | -0b1101010 | 0b10010111
-106 | -0b1101010 | -0b1101011 | 0b10010110
-107 | -0b1101011 | -0b1101100 | 0b10010101
-108 | -0b1101100 | -0b1101101 | 0b10010100
-109 | -0b1101101 | -0b1101110 | 0b10010011
-110 | -0b1101110 | -0b1101111 | 0b10010010
-111 | -0b1101111 | -0b1110000 | 0b10010001
-112 | -0b1110000 | -0b1110001 | 0b10010000
-113 | -0b1110001 | -0b1110010 | 0b10001111
-114 | -0b1110010 | -0b1110011 | 0b10001110
-115 | -0b1110011 | -0b1110100 | 0b10001101
-116 | -0b1110100 | -0b1110101 | 0b10001100
-117 | -0b1110101 | -0b1110110 | 0b10001011
-118 | -0b1110110 | -0b1110111 | 0b10001010
-119 | -0b1110111 | -0b1111000 | 0b10001001
-120 | -0b1111000 | -0b1111001 | 0b10001000
-121 | -0b1111001 | -0b1111010 | 0b10000111
-122 | -0b1111010 | -0b1111011 | 0b10000110
-123 | -0b1111011 | -0b1111100 | 0b10000101
-124 | -0b1111100 | -0b1111101 | 0b10000100
-125 | -0b1111101 | -0b1111110 | 0b10000011
-126 | -0b1111110 | -0b1111111 | 0b10000010
-127 | -0b1111111 | -0b10000000 | 0b10000001
-128 | -0b10000000 | -0b0000001 | 0b10000000

负数的补码计算

​ 为什么int8的负整数a的补码可以通过uint8(a)求得?

算术操作符(7个)

+

​ 加法、字符串连接符。

加法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"

func main() {
	a := int8(126)
	b := int8(127)
	c := int8(1)
	r1 := a + c
	r2 := b + c
	fmt.Printf("int8 %d + %d = %d\n", a, c, a+c)
	fmt.Printf("int8 %d + %d = %d\n", a, c, r1)
	fmt.Printf("int8 %d + %d = %d\n", b, c, b+c)
	fmt.Printf("int8 %d + %d = %d\n", b, c, r2)

	d := int8(-127)
	e := int8(-128)
	f := int8(-1)
	r3 := d + f
	r4 := e + f
	fmt.Printf("int8 %d + %d = %d\n", d, f, d+f)
	fmt.Printf("int8 %d + %d = %d\n", d, f, r3)
	fmt.Printf("int8 %d + %d = %d\n", e, f, e+f)
	fmt.Printf("int8 %d + %d = %d\n", e, f, r4)
}
int8 126 + 1 = 127
int8 126 + 1 = 127
int8 127 + 1 = -128
int8 127 + 1 = -128
int8 -127 + -1 = -128
int8 -127 + -1 = -128
int8 -128 + -1 = 127
int8 -128 + -1 = 127

字符串连接符

-

​ 减法。

*

​ 乘法。

/

​ 除法。

​ 若两个操作数都是整数,结果是整数(向0取整); ​ 若两个操作数都是浮点数,则结果是浮点数; ​ 若一整数一浮点数,则编译报错:invalid operation: 变量1 / 变量2 (mismatched types int and float64)

%

​ 取余

++

​ Go语言中++是一个语句,且只有后置++,而没有前置++

--

​ Go语言中——是一个语句,且只有后置——,而没有前置——

赋值操作符(11个)

+=

-=

*=

/=

%=

&=

|=

^=

<<=

>>=

逻辑操作符(3个)

&&

​ 逻辑与

||

​ 逻辑或

!

​ 逻辑非

比较操作符(6个)

==

!=

<

>

<=

>=

位操作符(6个)

&

​ 按位与。

只能用于相同的整数类型(int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64),即操作符两边的数据类型必须是相同的整数类型。

a & b 的运算规则:

  • 如果 ab 中某一位都为 1,则结果的对应位为 1
  • 如果 ab 中某一位有一个为 0,则结果的对应位为 0
  • 不能忽略符号位,即符号位也参与运算。
  • 负数是用其补码形式进行运算(提示:负数在内存中的表示形式其实就是以补码的形式,故进行&操作时不用手动转换成补码的形式,以下示例中的补码,只是为了方便理解)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package main

import "fmt"

func main() {
	a := int8(8)
	b := int8(11)
	c := int8(-8)
	d := int8(-11)
	fmt.Printf("a&b\na=%08b a补=%08b\nb=%08b b补=%08b\nr=%08b r补=%08b\n----\n", a, uint8(a), b, uint8(b), a&b, uint8(a&b))
	fmt.Printf("c&d\nc=%08b c补=%08b\nd=%08b d补=%08b\nr=%08b r补=%08b\n----\n", c, uint8(c), d, uint8(d), c&d, uint8(c&d))
	fmt.Printf("a&d\na=%08b a补=%08b\nd=%08b c补=%08b\nr=%08b r补=%08b\n----\n", a, uint8(a), d, uint8(d), a&d, uint8(a&d))
	fmt.Printf("d&a\nd=%08b d补=%08b\na=%08b a补=%08b\nr=%08b r补=%08b\n----\n", d, uint8(d), a, uint8(a), d&a, uint8(d&a))
	fmt.Printf("b&c\nb=%08b b补=%08b\nc=%08b c补=%08b\nr=%08b r补=%08b\n----\n", b, uint8(b), c, uint8(c), b&c, uint8(b&c))
	fmt.Printf("c&b\nc=%08b c补=%08b\nb=%08b b补=%08b\nr=%08b r补=%08b\n----\n", c, uint8(c), b, uint8(b), c&b, uint8(c&b))

}
a&b
a=00001000 a补=00001000
b=00001011 b补=00001011
r=00001000 r补=00001000
----
c&d
c=-0001000 c补=11111000
d=-0001011 d补=11110101
r=-0010000 r补=11110000
----
a&d
a=00001000 a补=00001000
d=-0001011 c补=11110101
r=00000000 r补=00000000
----
d&a
d=-0001011 d补=11110101
a=00001000 a补=00001000
r=00000000 r补=00000000
----
b&c
b=00001011 b补=00001011
c=-0001000 c补=11111000
r=00001000 r补=00001000
----
c&b
c=-0001000 c补=11111000
b=00001011 b补=00001011
r=00001000 r补=00001000
----

|

​ 按位或。

只能用于相同的整数类型(int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64),即操作符两边的数据类型必须是相同的整数类型。

a | b 的运算规则:

  • 如果 ab 中某一位有一个为 1,则结果的对应位为 1
  • 如果 ab 中某一位都为 0,则结果的对应位为 0
  • 不能忽略符号位,即符号位也参与运算。
  • 负数是用其补码形式进行运算(提示:负数在内存中的表示形式其实就是以补码的形式,故进行|操作时不用手动转换成补码的形式,以下示例中的补码,只是为了方便理解)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package main

import "fmt"

func main() {
	a := int8(8)
	b := int8(11)
	c := int8(-8)
	d := int8(-11)
	fmt.Printf("a|b\na=%08b a补=%08b\nb=%08b b补=%08b\nr=%08b r补=%08b\n----\n", a, uint8(a), b, uint8(b), a|b, uint8(a|b))
	fmt.Printf("c|d\nc=%08b c补=%08b\nd=%08b d补=%08b\nr=%08b r补=%08b\n----\n", c, uint8(c), d, uint8(d), c|d, uint8(c|d))
	fmt.Printf("a|d\na=%08b a补=%08b\nd=%08b c补=%08b\nr=%08b r补=%08b\n----\n", a, uint8(a), d, uint8(d), a|d, uint8(a|d))
	fmt.Printf("d|a\nd=%08b d补=%08b\na=%08b a补=%08b\nr=%08b r补=%08b\n----\n", d, uint8(d), a, uint8(a), d|a, uint8(d|a))
	fmt.Printf("b|c\nb=%08b b补=%08b\nc=%08b c补=%08b\nr=%08b r补=%08b\n----\n", b, uint8(b), c, uint8(c), b|c, uint8(b|c))
	fmt.Printf("c|b\nc=%08b c补=%08b\nb=%08b b补=%08b\nr=%08b r补=%08b\n----\n", c, uint8(c), b, uint8(b), c|b, uint8(c|b))

}
a|b
a=00001000 a补=00001000
b=00001011 b补=00001011
r=00001011 r补=00001011
----
c|d
c=-0001000 c补=11111000
d=-0001011 d补=11110101
r=-0000011 r补=11111101
----
a|d
a=00001000 a补=00001000
d=-0001011 c补=11110101
r=-0000011 r补=11111101
----
d|a
d=-0001011 d补=11110101
a=00001000 a补=00001000
r=-0000011 r补=11111101
----
b|c
b=00001011 b补=00001011
c=-0001000 c补=11111000
r=-0000101 r补=11111011
----
c|b
c=-0001000 c补=11111000
b=00001011 b补=00001011
r=-0000101 r补=11111011
----

^

按位异或。或者,也可以表示按位取反

按位异或

只能用于相同的整数类型(int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64),即操作符两边的数据类型必须是相同的整数类型。

a ^ b 的运算规则是:

  • 如果 ab 中某一位不同,则结果的对应位为 1
  • 如果 ab 中某一位相同,则结果的对应位为 0
  • 不能忽略符号位,即符号位也参与运算。
  • 遇到负数则将其表示成补码后,再进行运算(负数在内存中的表示形式其实就是以补码的形式,故进行^操作时不用手动转换成补码的形式)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package main

import "fmt"

func main() {
	a := int8(8)
	b := int8(11)
	c := int8(-8)
	d := int8(-11)
	fmt.Printf("a^b\na=%08b a补=%08b\nb=%08b b补=%08b\nr=%08b r补=%08b\n----\n", a, uint8(a), b, uint8(b), a^b, uint8(a^b))
	fmt.Printf("c^d\nc=%08b c补=%08b\nd=%08b d补=%08b\nr=%08b r补=%08b\n----\n", c, uint8(c), d, uint8(d), c^d, uint8(c^d))
	fmt.Printf("a^d\na=%08b a补=%08b\nd=%08b c补=%08b\nr=%08b r补=%08b\n----\n", a, uint8(a), d, uint8(d), a^d, uint8(a^d))
	fmt.Printf("d^a\nd=%08b d补=%08b\na=%08b a补=%08b\nr=%08b r补=%08b\n----\n", d, uint8(d), a, uint8(a), d^a, uint8(d^a))
	fmt.Printf("b^c\nb=%08b b补=%08b\nc=%08b c补=%08b\nr=%08b r补=%08b\n----\n", b, uint8(b), c, uint8(c), b^c, uint8(b^c))
	fmt.Printf("c^b\nc=%08b c补=%08b\nb=%08b b补=%08b\nr=%08b r补=%08b\n----\n", c, uint8(c), b, uint8(b), c^b, uint8(c^b))

}
a^b
a=00001000 a补=00001000
b=00001011 b补=00001011
r=00000011 r补=00000011
----
c^d
c=-0001000 c补=11111000
d=-0001011 d补=11110101
r=00001101 r补=00001101
----
a^d
a=00001000 a补=00001000
d=-0001011 c补=11110101
r=-0000011 r补=11111101
----
d^a
d=-0001011 d补=11110101
a=00001000 a补=00001000
r=-0000011 r补=11111101
----
b^c
b=00001011 b补=00001011
c=-0001000 c补=11111000
r=-0001101 r补=11110011
----
c^b
c=-0001000 c补=11111000
b=00001011 b补=00001011
r=-0001101 r补=11110011
----

按位取反

只能用于相同的整数类型。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package main

import "fmt"

func main() {
	a := int8(8)
	c := int8(-8)
	fmt.Printf("^a\na=%08b a补=%08b <- %d\nr=%08b r补=%08b <- %d\n----\n", a, uint8(a), a, ^a, uint8(^a), ^a)
	fmt.Printf("^c\na=%08b c补=%08b <- %d\nr=%08b r补=%08b <- %d\n----\n", c, uint8(c), c, ^c, uint8(^c), ^c)

}
^a
a=00001000 a补=00001000 <- 8
r=-0001001 r补=11110111 <- -9
----
^c
a=-0001000 c补=11111000 <- -8
r=00000111 r补=00000111 <- 7
----

&^

​ 按位清除。

只能用于相同的整数类型,即操作符两边的数据类型必须是相同的整数类型。

​ 具体来说,a &^ b 的运算规则是:

  • 如果 b 中某一位是 1,则 a 对应的那一位会被清零(即变成 0)。
  • 如果 b 中某一位是 0,则 a 对应的那一位保持不变。
  • 不能忽略符号位,即符号位也参与运算。
  • 遇到负数则将其表示成补码后,再进行运算(负数在内存中的表示形式其实就是以补码的形式,故进行&^操作时不用手动转换成补码的形式)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func main() {
	a := int8(8)
	b := int8(11)
	c := int8(-8)
	d := int8(-11)
	fmt.Printf("a&^b\na=%08b a补=%08b\nb=%08b b补=%08b\nr=%08b r补=%08b\n----\n", a, uint8(a), b, uint8(b), a&^b, uint8(a&^b))
	fmt.Printf("c&^d\nc=%08b c补=%08b\nd=%08b d补=%08b\nr=%08b r补=%08b\n----\n", c, uint8(c), d, uint8(d), c&^d, uint8(c&^d))
	fmt.Printf("a&^d\na=%08b a补=%08b\nd=%08b c补=%08b\nr=%08b r补=%08b\n----\n", a, uint8(a), d, uint8(d), a&^d, uint8(a&^d))
	fmt.Printf("d&^a\nd=%08b d补=%08b\na=%08b a补=%08b\nr=%08b r补=%08b\n----\n", d, uint8(d), a, uint8(a), d&^a, uint8(d&^a))
	fmt.Printf("b&^c\nb=%08b b补=%08b\nc=%08b c补=%08b\nr=%08b r补=%08b\n----\n", b, uint8(b), c, uint8(c), b&^c, uint8(b&^c))
	fmt.Printf("c&^b\nc=%08b c补=%08b\nb=%08b b补=%08b\nr=%08b r补=%08b\n----\n", c, uint8(c), b, uint8(b), c&^b, uint8(c&^b))


	// e := uint(256255)
	// fmt.Printf("a&^e\na=%08b\ne=%08b\nr=%08b\n----\n", a, e, a&^e) //invalid operation: a &^ e (mismatched types int8 and uint)
	// f := int16(11)
	// fmt.Printf("a&^f\na=%08b\nf=%08b\nr=%08b\n----\n", a, f, a&^f) //invalid operation: a &^ f (mismatched types int8 and int16)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
a&^b
a=00001000 a补=00001000
b=00001011 b补=00001011
r=00000000 r补=00000000
----
c&^d
c=-0001000 c补=11111000
d=-0001011 d补=11110101
r=00001000 r补=00001000
----
a&^d
a=00001000 a补=00001000
d=-0001011 c补=11110101
r=00001000 r补=00001000
----
d&^a
d=-0001011 d补=11110101
a=00001000 a补=00001000
r=-0001011 r补=11110101
----
b&^c
b=00001011 b补=00001011
c=-0001000 c补=11111000
r=00000011 r补=00000011
----
c&^b
c=-0001000 c补=11111000
b=00001011 b补=00001011
r=-0010000 r补=11110000
----

>>

​ 二进制左移位

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import "fmt"

func main() {
	a := int8(8)
	b := uint8(8)
	c := int8(-8)
	fmt.Printf("a=%08b\n", a)

	fmt.Printf("a << 1 = %08b -> %d\n", a<<1, a<<1)
	fmt.Printf("a << 2 = %08b -> %d\n", a<<2, a<<2)
	fmt.Printf("a << 4 = %08b -> %d\n", a<<4, a<<3)
	fmt.Printf("a << 5 = %08b -> %d\n", a<<5, a<<4)
	fmt.Printf("a << 6 = %08b -> %d\n", a<<6, a<<6)
	fmt.Printf("b=%08b\n", b)
	fmt.Printf("b << 1 = %08b -> %d\n", b<<1, b<<1)
	fmt.Printf("b << 2 = %08b -> %d\n", b<<2, b<<2)
	fmt.Printf("b << 4 = %08b -> %d\n", b<<4, b<<4)
	fmt.Printf("b << 5 = %08b -> %d\n", b<<5, b<<5)
	fmt.Printf("b << 6 = %08b -> %d\n", b<<6, b<<6)
	fmt.Printf("c=%09b\n", c)
	fmt.Printf("c << 1 = %08b -> %d\n", c<<1, c<<1)
	fmt.Printf("c << 2 = %08b -> %d\n", c<<2, c<<2)
	fmt.Printf("c << 4 = %08b -> %d\n", c<<4, c<<4)
	fmt.Printf("c << 5 = %08b -> %d\n", c<<5, c<<5)
	fmt.Printf("c << 6 = %08b -> %d\n", c<<6, c<<6)

}
a=00001000
a << 1 = 00010000 -> 16
a << 2 = 00100000 -> 32
a << 4 = -10000000 -> 64
a << 5 = 00000000 -> -128
a << 6 = 00000000 -> 0
b=00001000
b << 1 = 00010000 -> 16
b << 2 = 00100000 -> 32
b << 4 = 10000000 -> 128
b << 5 = 00000000 -> 0
b << 6 = 00000000 -> 0
c=-00001000
c << 1 = -0010000 -> -16
c << 2 = -0100000 -> -32
c << 4 = -10000000 -> -128
c << 5 = 00000000 -> 0
c << 6 = 00000000 -> 0

​ 可以看出,对于有符号的整数,移位时,最高位若是1,则当成负数。

>>

二进制右移位

指针操作符(2个)

*

​ 声明指针变量、解引用指针。

&

​ 获取变量的地址。

其他操作符和标点符号(12个)

(

​ 左括号,用于运算时分组、import分组、函数或方法的定义以及调用,以及变量定义、常量定义、类型定义时共用var、const、type关键字

)

​ 右括号,用于运算时分组、import分组、函数或方法的定义以及调用,以及变量定义、常量定义、类型定义时共用var、const、type关键字

[

​ 左方括号,用于切片、数组的定义,以及切片、数组获取指定索引的值、map获取指定键的值时使用。

]

​ 右方括号,用于切片、数组的定义,以及切片、数组获取指定索引的值、map获取指定键的值时使用。

{

​ 用于切片、数组、map等字面值,以及函数、方法、接口、结构体的定义

}

​ 用于切片、数组、map等字面值,以及函数、方法、接口、结构体的定义

:=

​ 用于短变量声明

.

​ 调用实例的方法、指定包中的函数或方法

,

​ 逗号分隔符

;

​ 分号,位于语句末尾,则分号可省略,若一行中有多个语句,则中间语句后面的分号不可省略

...

​ 1.放在函数或方法的形参列表的最后一项前,表示该函数或方法接收任意多个实参; ​ 2.放在append内置函数的形参列表的最后一项后(最后一项必须是字符串类型、切片类型, ​ 对于切片,则其元素的类型必须与append函数的第一个实参的元素类型一致, ​ 对于字符串类型,则append函数的第一个实参的元素类型必须是byte类型)

:

1.定义标签后跟的一个冒号(goto语句跳转指定的标签、break指定的标签等); 2.case、default语句后跟的一个冒号; 3.结构体字段标签中的一个冒号; 4.切片表达式中的一个冒号;

~

​ 指定基础类型

->

​ channel操作

|

​ 用于类型联合

操作符优先级

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
优先级从高到低排列1一元操作符右结合性+正号-负号!逻辑非^按位取反*指针解引用&取地址<-接收运算符用于从通道中接收数据
2乘法除法和取余左结合性*乘法/除法%取余<<左移>>右移&按位与&^按位清除
3加法和减法左结合性+加法-减法|按位或^按位异或
4关系操作符
==等于!=不等于<小于<=小于等于>大于>=大于等于
5逻辑运算符
&&逻辑与||逻辑或

6赋值运算符右结合性=赋值+=加后赋值-=减后赋值*=乘后赋值/=除后赋值%=取余后赋值<<=左移后赋值>>=右移后赋值&=按位与后赋值&^=按位清除后赋值|=按位或后赋值^=按位异或后赋值
7其他运算符左结合性,逗号用于多变量声明和函数参数列表

操作符的结合性

​ 参见以上优先级部分。

最后修改 October 10, 2024: 更新 (a4b8f85)