Edited at

Swift演算子まとめ

Swiftの演算子、まとめました。

【2018/09/05追記】

内容はSwift2のものであり、(筆者がiOS開発を離れているため)更新の予定もありません😉

編集リクエストは大歓迎です。@BlueRayi さんありがとうございました。


演算子一覧

Prefix演算子

演算子
作用

++
1加算※

--
1減算※

!
論理NOT

~
ビットNOT

+ (単項)
+符号

- (単項)
-符号

Postfix演算子

演算子
説明

++
1加算※

--
1減算※

Infix演算子

演算子
説明
結合律
優先順位

<<
左ビットシフト
無結合
160

>>
右ビットシフト
無結合
160

*
乗算
左結合
160

/
除算
左結合
160

%
剰余
左結合
160

&*
オーバーフロー乗算
左結合
160

&
ビットAND
左結合
160

+
加算
左結合
140

-
減算
左結合
140

&+
オーバーフロー加算
左結合
140

&-
オーバーフロー減算
左結合
140

|
ビットOR
左結合
140

^
ビットXOR
左結合
140

..<
半開区間
無結合
135

...
閉区間
無結合
135

is
型チェック
左結合
132

as as? as!
型キャスト
左結合
132

??
Nil Coalescing
右結合
131

<
未満
無結合
130

<=
以下
無結合
130

>
より上
無結合
130

>=
以上
無結合
130

==
イコール
無結合
130

!=
ノットイコール
無結合
130

===
同じオブジェクト
無結合
130

!==
違うオブジェクト
無結合
130

~=
パターンマッチ
無結合
130

&&
論理AND
左結合
120

||
論理OR
左結合
110

?:
三項条件
右結合
100

=
代入
右結合
90

*=
乗算と代入
右結合
90

/=
徐算と代入
右結合
90

%=
剰余と代入
右結合
90

+=
加算と代入
右結合
90

-=
減算と代入
右結合
90

<<=
左ビットシフトと代入
右結合
90

>>=
右ビットシフトと代入
右結合
90

&=
ビットANDと代入
右結合
90

|=
ビットORと代入
右結合
90

^=
ビットNOTと代入
右結合
90

&&=
論理ANDと代入
右結合
90

||=
論理ORと代入
右結合
90

※…++演算子、--演算子はSwift3.0で削除された。


用語

単項演算子(Unary)

被演算子(Operand)が1つの演算子。

前置のもの(prefix)と後置のもの(postfix)がある。

二項演算子(Binary)

被演算子が2つの演算子。

被演算子の間に置かれる(infix)。

三項演算子(Ternary)

被演算子が3つの演算子。

?:の一つだけ(infix)。

優先順位

数値が大きいものほど先に演算される。

単項演算子は二項演算子よりも優先順位が高い。

結合律

優先順位が同じ演算子が並んだ場合は、左結合のものは左から、右結合のものは右から演算される。

(同じ優先順位で、左結合のものと右結合のものは混在しない。)

無結合の演算子が並んだ場合はエラーとなる。

let result = 2 + 3 + 4  // 左から

var str1: String?
var str2: String?
let string = str1 ?? str2 ?? "string" // 右から

let int1 = 1
let int2 = 2
let int3 = 3
int1 == int2 == int3 // エラー


各演算子


代入演算子(Assignment Operator)


=

値の代入。

タプルの場合はそれぞれに代入。

Objective-Cと異なり、値を返さない。

let (x, y) = (1, 2)

// x = 1, y = 2

if x = y { // 判定する値が返らない
// エラー
}


算術演算子


+, -, *, /

Objective-Cと異なり、オーバーフローを許容しない。

var i: Int8 = 127 // Int8の最大数

i++ // エラー


%

a % b は

a = (b * 整数) + 余り

と解釈される。

-9 % 4 // (4 * -2) - 1 

// -1
-9 % -4 // (-4 * 2) - 1
// -1

また、Float型にも適用可能。

8 % 2.5 // 0.5


++, --

それぞれ、1の加算、1の減算となる。

prefixは演算の後に値を返し、postfixは値を返した後に演算を行う。

Swift3.0からは削除されたため、+=演算子、-=演算子などを使って代用する(ただし、これらの演算子は値を返さない)。

var a = 0, b = 0

let c = ++a // 1
let d = b++ // 0


+, - (単項)

符号を表す。


オーバーフロー演算子


&+, &-, &*

オーバーフローを許容する演算子。

var i: Int8 = 127 // Int8の最大数

i &+ 1 // -128: Int8の最小数


比較演算子


==, !=, <, >, <=, >=

それぞれ比較の結果のBool値を返す。


===, !==

被演算子が同じオブジェクトを参照しているかどうかを判定する。

(被演算子はクラスのオブジェクト)


三項条件演算子


?:

Swift唯一の三項演算子。

let isSelected = true

if isSelected {
print("true")
} else {
print("false")
}
// ↓同じ
isSelected ? print("true") : print("false")


Nil Coalescing 演算子


??

a ?? b (aはオプショナル型)

aがnilのときbを返す演算子。

let integer: Int? = nil

let beta: Int = 10

alpha != nil ? alpha! : beta
// ↓同じ
alpha ?? beta


パターンマッチ


~=

パターンマッチの結果をBool値で返す。

区間(後述)のマッチによく使われる。

0...100 ~= 15 // true

switch文のcase分岐の際、内部で使われている演算子。


区間演算子

両側が整数 → Range型:for-inに使える。

片側or両側が浮動小数点数 → ClosedInterval型(閉区間)、HalfOpenInterval型(半開区間):for-inに使えない。


...

閉区間:右側の数が含まれる区間。

0...100 ~= 100 // true


..<

半開区間:右側の数を含まない区間。

0..<100 ~= 100 // false


論理演算子(Logical Operators)

Swiftで論理演算子の被演算子となるはBool型のみ。


!

論理NOT

var isSelected: Bool = true

!isSelected // false


&&

論理AND

0
1

0
0
0

1
0
1

(便宜的に、0: false, 1: true)


||

論理OR

0
1

0
0
1

1
1
1

(便宜的に、0: false, 1: true)


ビット演算子

整数値を2進数で表したとき、それぞれの桁同士を論理演算した値を返す。


~

ビットNOT

それぞれの桁同士にNOT演算。

let bit: UInt8 = 0b00001111 // = 15

// ↓
~bit // 0b11110000 = 240

(0bは2進数を表すリテラル。)


&

ビットAND

それぞれの桁同士にAND演算。

let bit1: UInt8 = 0b11111100 // = 252

let bit2: UInt8 = 0b11110000 // = 240
// ↓
bit1 & bit2 // 0b11110000 = 240


|

ビットOR

それぞれの桁同士にOR演算。

let bit1: UInt8 = 0b11111100 // = 252

let bit2: UInt8 = 0b11110000 // = 240
// ↓
bit1 | bit2 // 0b11111100 = 252


^

ビットXOR

それぞれの桁同士にXOR演算。

XOR演算は以下の表の通り。

0
1

0
0
1

1
1
0

(0: false, 1: true)

let bit1: UInt8 = 0b11111100 // = 252

let bit2: UInt8 = 0b11110000 // = 240
// ↓
bit1 ^ bit2 // 0b00001100 = 12


<<, >>

ビットシフト演算子

それぞれの桁を右または左に指定した値シフトする。

シフトにより空いた桁を埋める値は、整数型が符号ありか符号なしかで異なる。


  • 符号なし整数(Unsigned Int)

シフトにより空いた桁を0で埋める

let unsignedInt: UInt8 = 0b11111111 // 255

// ↓
unsignedInt << 4 // 0b11110000 = 240
unsignedInt >> 4 // 0b00001111 = 15


  • 符号あり整数(Signed Int)

最上位の桁は符号ビット(the sign bit)といい、0で正、1で負を表す。

符号あり整数の場合、シフトにより空いた桁は符号ビットの値で埋められる。

let signedPlusInt: Int8 = 127 // 0b0_1111111

signedPlusInt >> 4 // 0b0_0000111 = 7
signedPlusInt << 4 // 0b1_1110000 = -16
// 空いた桁を0で埋めている

let signedMinusInt: Int8 = -127 // 0b1_0000000
signedMinusInt >> 4 // 0b1_1111000 = -8
signedMinusInt << 4 // 0b0_0001111 = 16
// 空いた桁を1で埋めている

参考:マイナス値の2進数での表し方


複合代入演算子

各々の演算後に、結果を代入する演算子。


+=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^=, &&=, ||=

var int: Int = 3

int += 5
// ↓同じ
int = int + 5

var bit: UInt8 = 0b11110000 // 240

bit <<= 4 // 0b00000000 = 0
// ↓同じ
bit = bit << 4


型チェック、型キャスト


is

型チェック。

左項のオブジェクトが右項の型に一致すればtrue、異なればfalseを返す。

let str: Any = "string"

str is String // true


as, as? as!

ダウンキャストを行う。

let str: String = "string"

str as NSString

as!はダウンキャストに失敗した場合、クラッシュする。

as?はダウンキャストに失敗した場合、nilが入る。

let str: Any = "string"

str as! Int // 実行時エラー
str as? Int // nil


演算子オーバーロード

既存の演算子の書き換え・定義されてない型への定義。

オーバーロードとカスタム演算子(後述)の導入が可能なのは単項演算子と二項演算子のみ。

書き換えは用法と用量を守りましょう。

// * を + に書き換え

func * (left: Int, right: Int) -> Int {
return left + right
}

2 * 3 // 5

// 左側;String、右側:Intに + を定義
func + (left: String, right: Int) -> String {
return left + String(right)
}

"Number: " + 3 // "Number: 3"


カスタム演算子

新たに演算子を定義。

// 累乗を計算する演算子を定義

infix operator ** { associativity left precedence 161 }
func ** (left: Int, right: UInt) -> Int {
var powered = 1
for _ in 0..<right {
powered *= left
}

return powered
}

2 + 3 ** 2 // 11


参考文献

The Swift Programming Language

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html#//apple_ref/doc/uid/TP40014097-CH6-ID60

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_StandardLibrary_Operators/index.html#//apple_ref/swift/opfunc/s:ZFSsoi2teuRq_Ss9Equatable_FTq_q__Sb

開発のプロが教える-Swift標準ガイドブック

http://www.amazon.co.jp/開発のプロが教える-Swift標準ガイドブック-渡辺-龍司/dp/4839953546


おわりに

Qiita初投稿でした!楽しかったです!

"プログラミングガイドを読むべし"みたいな話を何度か聞いたことがあったのですが、「参考書の方が速く読めるし、物によるけど説明も丁寧だし、、」と敬遠してきました。

今回初めてプログラミングガイドにしっかりと目を通し、「全部書いてある...。(当然)」と。

原典にあたる大切さを実感として得ることができました。

ビット演算子等まだ理解が及ばない部分も多いので、間違い等ありましたらご指摘下さい。

こういったイベントに積極的に参加する会社っていいですね!(宣伝)