🌈

これで完璧!Goの演算子と区切り記号を網羅するまとめ

に公開

はじめに

Go 言語仕様では、演算子や句読点(トークン)があらかじめ定義され、プログラム中で特別な意味を持ちます。
知らない演算子がたくさんあったので、この機会にまとめてみました。

http://go.dev/ref/spec#Operators_and_punctuation

一覧表

トークン 説明 使用例
+ 加算/正符号 sum := a + b
- 減算/負符号 diff := a - b
* 乗算/ポインタ参照 prod := a * b
/ 除算 quot := a / b
% 剰余 rem := a % b
<< 左シフト s := x << 2
>> 右シフト s := x >> 1
& ビットAND/アドレス演算子 c := a & b
| ビットOR c := a | b
^ ビットXOR c := a ^ b
&^ ビットクリア (AND NOT) c := a &^ b
== 等価 if x == y {}
!= 不等価 if x != y {}
< 未満 if x < y {}
<= 以下 if x <= y {}
> 超過 if x > y {}
>= 以上 if x >= y {}
&& 論理AND if ok && done {}
|| 論理OR if err != nil || retry {}
! 論理NOT if !flag {}
<- チャネル受信 v := <-ch
++ インクリメント i++
-- デクリメント i--
= 代入 x = y
:= 省略形変数宣言+代入 x := 10
+= 加算代入 x += 5
-= 減算代入 x -= 3
*= 乗算代入 x *= 2
/= 除算代入 x /= 4
%= 剰余代入 x %= 3
<<= 左シフト代入 x <<= 1
>>= 右シフト代入 x >>= 2
&= ビットAND代入 x &= y
|= ビットOR代入 x |= y
^= ビットXOR代入 x ^= y
&^= ビットクリア代入 x &^= mask
... 可変長パラメータ/スライス展開 append(s, xs...)
. セレクタ/小数点 p.X
, 区切り fmt.Println(a, b)
; 文終端 i := 0; j := 1
: ラベル/マップキー指定 Label: for i := range arr {}
( ) グループ化/関数呼び出し r := (a + b) * c
[ ] 配列・スライス・マップ参照 v := arr[1]
{ } ブロック/構造体リテラル if x > 0 { fmt.Println(x) }
~ チルト(未使用/将来予約)

参照: Go 言語仕様 “Operators and punctuation” (https://go.dev/ref/spec#Operators)

+

  • 説明
    2つの数値を加算します
  • 使用例
    package main
    import "fmt"
    func main() {
        a := 3
        b := 5
        fmt.Println(a + b)
    }
    // 出力: 8
    

-

  • 説明
    左辺から右辺を減算します(負符号としても使えます)
  • 使用例
    package main
    import "fmt"
    func main() {
        a := 9
        b := 4
        fmt.Println(a - b)
        fmt.Println(-a)
    }
    // 出力:
    // 5
    // -9
    

*

  • 説明
    左辺と右辺を乗算します(ポインタ参照にも使用)
  • 使用例
    package main
    import "fmt"
    func main() {
        a := 4
        b := 6
        fmt.Println(a * b)
        x := 7
        p := &x
        fmt.Println(*p)
    }
    // 出力:
    // 24
    // 7
    

/

  • 説明
    左辺を右辺で除算します
  • 使用例
    package main
    import "fmt"
    func main() {
        fmt.Println(20 / 4)
    }
    // 出力: 5
    

%

  • 説明
    剰余(余り)を計算します
  • 使用例
    package main
    import "fmt"
    func main() {
        fmt.Println(10 % 3)
    }
    // 出力: 1
    

<<

  • 説明
    左辺をビット単位で左にシフトします
  • 使用例
    package main
    import "fmt"
    func main() {
        fmt.Println(3 << 2)
    }
    // 出力: 12
    

>>

  • 説明
    左辺をビット単位で右にシフトします
  • 使用例
    package main
    import "fmt"
    func main() {
        fmt.Println(8 >> 2)
    }
    // 出力: 2
    

&

  • 説明
    ビット単位で AND 演算を行います(変数のアドレス取得にも使用)
  • 使用例
    package main
    import "fmt"
    func main() {
        a := 0b1100
        b := 0b1010
        fmt.Println(a & b)  // ビットAND
        x := 42
        fmt.Println(&x)     // アドレス取得
    }
    // 出力:
    // 8
    // 0xc0000120b0
    

|

  • 説明
    ビット単位で OR 演算を行います
  • 使用例
    package main
    import "fmt"
    func main() {
        a := 0b1001
        b := 0b0110
        fmt.Println(a | b)
    }
    // 出力: 15
    

^

  • 説明
    ビット単位で XOR 演算を行います
  • 使用例
    package main
    import "fmt"
    func main() {
        a := 5  // 0101
        b := 3  // 0011
        fmt.Println(a ^ b)
    }
    // 出力: 6
    

&^

  • 説明
    ビットクリア(AND NOT)演算を行います
  • 使用例
    package main
    import "fmt"
    func main() {
        a := 0b1111
        b := 0b0011
        fmt.Println(a &^ b)
    }
    // 出力: 12
    

==

  • 説明
    2つの値が等しいかどうかを比較します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 10
        y := 10
        fmt.Println(x == y)
    }
    // 出力: true
    

!=

  • 説明
    2つの値が等しくないかどうかを比較します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 7
        y := 3
        fmt.Println(x != y)
    }
    // 出力: true
    

<

  • 説明
    左辺が右辺より小さいかどうかを比較します
  • 使用例
    package main
    import "fmt"
    func main() {
        fmt.Println(2 < 5)
    }
    // 出力: true
    

<=

  • 説明
    左辺が右辺以下かどうかを比較します
  • 使用例
    package main
    import "fmt"
    func main() {
        fmt.Println(5 <= 5)
    }
    // 出力: true
    

>

  • 説明
    左辺が右辺より大きいかどうかを比較します
  • 使用例
    package main
    import "fmt"
    func main() {
        fmt.Println(9 > 2)
    }
    // 出力: true
    

>=

  • 説明
    左辺が右辺以上かどうかを比較します
  • 使用例
    package main
    import "fmt"
    func main() {
        fmt.Println(8 >= 8)
    }
    // 出力: true
    

&&

  • 説明
    2つの条件がともに真のときに真を返す論理 AND 演算子です
  • 使用例
    package main
    import "fmt"
    func main() {
        ok := true
        done := false
        if ok && !done {
            fmt.Println("Ready")
        }
    }
    // 出力: Ready
    

||

  • 説明
    いずれかの条件が真なら真を返す論理 OR 演算子です
  • 使用例
    package main
    import "fmt"
    func main() {
        err := error(nil)
        retry := true
        if err != nil || retry {
            fmt.Println("Retry")
        }
    }
    // 出力: Retry
    

!

  • 説明
    ブール値を反転(NOT)します
  • 使用例
    package main
    import "fmt"
    func main() {
        flag := false
        fmt.Println(!flag)
    }
    // 出力: true
    

<-

  • 説明
    チャネルからの受信(左辺)または送信(右辺)に使用します
  • 使用例
    package main
    import "fmt"
    func main() {
        ch := make(chan int, 1)
        ch <- 7
        v := <-ch
        fmt.Println(v)
    }
    // 出力: 7
    

++

  • 説明
    変数を1だけ増加させます
  • 使用例
    package main
    import "fmt"
    func main() {
        i := 0
        i++
        fmt.Println(i)
    }
    // 出力: 1
    

--

  • 説明
    変数を1だけ減少させます
  • 使用例
    package main
    import "fmt"
    func main() {
        i := 2
        i--
        fmt.Println(i)
    }
    // 出力: 1
    

=

  • 説明
    右辺の値を左辺の変数に代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 5
        y := 0
        y = x
        fmt.Println(y)
    }
    // 出力: 5
    

:=

  • 説明
    変数宣言と同時に代入を行う短縮記法です
  • 使用例
    package main
    import "fmt"
    func main() {
        msg := "hello"
        fmt.Println(msg)
    }
    // 出力: hello
    

+=

  • 説明
    左辺の変数に右辺を加算して再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 7
        x += 3
        fmt.Println(x)
    }
    // 出力: 10
    

-=

  • 説明
    左辺の変数から右辺を減算して再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 12
        x -= 5
        fmt.Println(x)
    }
    // 出力: 7
    

*=

  • 説明
    左辺の変数に右辺を乗算して再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 5
        x *= 4
        fmt.Println(x)
    }
    // 出力: 20
    

/=

  • 説明
    左辺の変数に右辺で除算した結果を再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 20
        x /= 5
        fmt.Println(x)
    }
    // 出力: 4
    

%=

  • 説明
    左辺の変数に右辺で剰余を計算した結果を再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 14
        x %= 5
        fmt.Println(x)
    }
    // 出力: 4
    

<<=

  • 説明
    左辺の変数をビット左シフトして再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 1
        x <<= 3
        fmt.Println(x)
    }
    // 出力: 8
    

>>=

  • 説明
    左辺の変数をビット右シフトして再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 16
        x >>= 3
        fmt.Println(x)
    }
    // 出力: 2
    

&=

  • 説明
    左辺の変数に右辺とのビットAND結果を再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 0b1111
        mask := 0b0101
        x &= mask
        fmt.Println(x)
    }
    // 出力: 5
    

|=

  • 説明
    左辺の変数に右辺とのビットOR結果を再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 0b1000
        mask := 0b0011
        x |= mask
        fmt.Println(x)
    }
    // 出力: 11
    

^=

  • 説明
    左辺の変数に右辺とのビットXOR結果を再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 0b0110
        mask := 0b0011
        x ^= mask
        fmt.Println(x)
    }
    // 出力: 5
    

&^=

  • 説明
    左辺の変数にビットクリア演算結果を再代入します
  • 使用例
    package main
    import "fmt"
    func main() {
        x := 0b1111
        mask := 0b0011
        x &^= mask
        fmt.Println(x)
    }
    // 出力: 12
    

...

  • 説明
    可変長引数の定義およびスライスの展開に使用します
  • 使用例
    package main
    import "fmt"
    func Sum(nums ...int) int {
        total := 0
        for _, n := range nums {
            total += n
        }
        return total
    }
    func main() {
        slice := []int{1, 2, 3}
        fmt.Println(Sum(slice...))
    }
    // 出力: 6
    

.

  • 説明
    構造体のフィールドアクセスや小数点で使用します
  • 使用例
    package main
    import "fmt"
    type Point struct{ X, Y int }
    func main() {
        p := Point{X:7, Y:8}
        fmt.Println(p.X)
        fmt.Println(3.14)
    }
    // 出力:
    // 7
    // 3.14
    

,

  • 説明
    関数呼び出しや複数代入で要素を区切ります
  • 使用例
    package main
    import "fmt"
    func main() {
        a, b := 2, 3
        fmt.Println(a, b)
    }
    // 出力: 2 3
    

;

  • 説明
    文の区切りに使います(多くの場合省略可能)
  • 使用例
    package main
    import "fmt"
    func main() {
        i := 0; j := 2; fmt.Println(i+j)
    }
    // 出力: 2
    

:

  • 説明
    ラベル定義やマップのキー・値区切りで使用します
  • 使用例
    package main
    import "fmt"
    func main() {
    Label:
        fmt.Println("label")
        m := map[string]int{"a":1}
        fmt.Println(m["a"])
    }
    // 出力:
    // label
    // 1
    

( )

  • 説明
    式のグループ化や関数呼び出しで使用します
  • 使用例
    package main
    import "fmt"
    func add(a, b int) int { return a + b }
    func main() {
        fmt.Println((2 + 3) * 4)
        fmt.Println(add(5, 6))
    }
    // 出力:
    // 20
    // 11
    

[ ]

  • 説明
    配列・スライス・マップのインデックス参照で使用します
  • 使用例
    package main
    import "fmt"
    func main() {
        arr := []string{"apple", "banana", "cherry"}
        m := map[string]int{"x": 100}
        fmt.Println(arr[1])
        fmt.Println(m["x"])
    }
    // 出力:
    // banana
    // 100
    

{ }

  • 説明
    ブロックの開始/終了や構造体リテラルで使用します
  • 使用例
    package main
    import "fmt"
    type P struct{ X, Y int }
    func main() {
        for i := 1; i <= 2; i++ {
            fmt.Println(i)
        }
        p := P{X:1, Y:2}
        fmt.Println(p)
    }
    // 出力:
    // 1
    // 2
    // {1 2}
    

~

  • 説明
    将来のために予約されたトークンで、現在は意味を持ちません
  • 使用例
    // Go では未使用の予約トークンです
    

Discussion