Go言語の式と演算子
2026/09/20

オペランドと演算子

オペランドは演算の対象となる値や式であり、演算子はそれらを結びつける記号です。演算子はオペランドの数に応じて二項演算子と単項演算子に分かれます。

二項演算子

二項演算子は2つのオペランドの間に置きます。

種類演算子
算術+ - * / %
ビット& | ^ &^ << >>
比較== != < <= > >=
論理&& ||
a, b := 1, 2
sum := a + b       // 3
masked := a & b    // 0
ok := a < b        // true
both := true && ok // true

単項演算子

単項演算子はオペランドの直前に置きます。Go言語では前置のみをサポートしています。

演算子意味
+値はそのまま
-正負の反転
!真偽値の反転
^ビットの反転
*ポインタが指す値の参照
&アドレスの取得
<-チャネルからの値の受信
pos := +10     // 10
neg := -10     // -10
on := true
stopped := !on // false
flipped := ^uint8(0b00001100) // 0b11110011

var n int = 10
p := &n
v := *p // 10

ch := make(chan int, 1)
ch <- 1
got := <-ch // 1

算術演算子

演算子意味対象
+加算、文字列の連結整数、浮動小数点、複素数、文字列
-減算整数、浮動小数点、複素数
*乗算整数、浮動小数点、複素数
/除算。整数除算はゼロ方向へ切り捨て整数、浮動小数点、複素数
%剰余整数
&ビット積整数
|ビット和整数
^排他的論理和整数
&^指定ビットの消去。右辺で1のビット位置を0にする整数
<<左シフト。右オペランドは0以上整数
>>右シフト。右オペランドは0以上整数
a, b := 10, 3
sum := a + b              // 13
joined := "go" + "lang"   // "golang"
diff := a - b             // 7
prod := a * b             // 30
quot := a / b             // 3
negQuot := (-10) / 3      // -3
rem := a % b              // 1

x, y := uint8(0b1100), uint8(0b1010)
bitAnd := x & y           // 8
bitOr := x | y            // 14
bitXor := x ^ y           // 6
bitClear := x &^ y        // 4
shiftLeft := x << 1       // 24
shiftRight := x >> 1      // 6

比較演算子

演算子意味対象
==等しい比較可能な型
!=等しくない比較可能な型
<より小さい順序付け可能な型
<=以下順序付け可能な型
>より大きい順序付け可能な型
>=以上順序付け可能な型

順序付け可能な型は整数、浮動小数点、文字列です。boolやポインタは等値比較はできても順序比較はできません。

スライス、マップ、関数は値同士を比較できませんが、いずれもnilとの等値比較は可能です。配列は要素型が比較可能であれば==で比較できます。

x, y := 1, 2
isLess := x < y            // true
isLessOrEqual := x <= y    // true
isGreater := x > y         // false
isGreaterOrEqual := x >= y // false
isEqual := x == y          // false
isNotEqual := x != y       // true

// []int{1} == []int{1}                   // コンパイルエラー: スライス同士は比較不可
// map[int]int{1: 1} == map[int]int{1: 1} // コンパイルエラー: マップ同士は比較不可
// func() {} == func() {}                 // コンパイルエラー: 関数同士は比較不可

var pending []int
isNil := pending == nil // true: スライス、マップ、関数はnilと比較可能

論理演算子

演算子意味
&&論理積
||論理和
!論理否定

&&と||は短絡評価します。&&は左辺がfalseなら右辺を評価しません。||は左辺がtrueなら右辺を評価しません。右辺に関数呼び出しなどの副作用がある場合でも、評価されない限り実行されません。

func sideEffect(n int) int { return n }

active := true
paused := !active // false

if false && sideEffect(2) == 2 {
    // 左辺がfalseのためsideEffectは評価されない
}

if true || sideEffect(2) == 2 {
    // 左辺がtrueのためsideEffectは評価されない
}

++と--

演算子意味
++1増やす
--1減らす

文であり、式としては扱えません。前置の++iはなく、f(i++)のように式のオペランドに含めることもできません。

i := 0
i++
i--

// f(i++) // コンパイルエラー: 文のため式の中では使えない

型変換

二項演算子のオペランドは、シフト演算と非型付き定数を除き同一の型でなければなりません。型付きの変数同士に暗黙の数値変換はないため、intとfloat64をそのまま計算するとコンパイルエラーになります。一方のオペランドが非型付き定数なら、相手の型で表現できる値であればその型として使えます。

var x int = 1
var y float64 = 2
// z := x + y // コンパイルエラー: 型の異なる変数同士は演算不可
mixed := float64(x) + y
sum := x + 2 // 非型付き定数2はintとして扱われる

ifやforの条件式と論理演算子のオペランドは真偽値に限ります。boolのほか、基底型がboolの型も使えます。数値や文字列からboolへの暗黙変換はなく、bool(n)のような明示的な変換もありません。真偽判定には比較式を用います。

n := 1
s := "go"
var err error

// if n { }      // コンパイルエラー: 条件式は真偽値が必要
// if s { }      // コンパイルエラー
// ok := bool(n) // コンパイルエラー: intからboolへの変換は不可

hasN := n != 0       // true
hasS := s != ""      // true
hasErr := err != nil // false

定数式

定数式は定数のみで構成され、コンパイル時に計算されます。計算結果は定数の宣言や配列の要素数指定などにそのまま利用できます。

const size = 1 + 2*3
var arr [size]int

演算子の優先順位

二項演算子

仕様では優先度1から5まで定義されており、数値が大きいほど強く結合し、先に計算されます。

優先度演算子
5* / % << >> & &^
4+ - | ^
3== != < <= > >=
2&&
1||

同じ優先度の二項演算子は左から右へ結合します。たとえば42 + a - bは(42 + a) - bと解釈されます。

n := 1 + 2*3 // 乗算が優先され7になる

単項演算子

単項演算子は、すべての二項演算子よりも強く結合します。++と--は文であるため優先順位の定義には含まれません。

x := uint8(0b1100)
n := ^x >> 1 // 単項演算の^xが優先されるため121

評価順序

関数呼び出し、メソッド呼び出し、チャネル受信、二項論理演算は、記述された順序に従って左から右へ評価されます。たとえばf() + g()ではf()が先に実行されてからg()が実行されます。関数の引数同士も同様で、sub(next(), next())では左側のnext()が先に呼び出されます。

一方、変数の参照と関数呼び出しの相対的な評価順序は仕様で定められていません。

func f() int { return 1 }
func g() int { return 2 }

sum := f() + g() // f()の実行後にg()が実行され3になる

var seq int

func next() int {
    seq++
    return seq
}

func sub(a, b int) int { return a - b }

sub(next(), next()) // 左辺が1、右辺が2となり常に-1

n := 1
inc := func() int { n++; return n }
pair := []int{n, inc()} // nの参照とinc()の実行順序が未規定のため[1, 2]または[2, 2]