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 alpha: 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で埋めている
複合代入演算子
各々の演算後に、結果を代入する演算子。
+=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^=, &&=, ||=
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初投稿でした!楽しかったです!
"プログラミングガイドを読むべし"みたいな話を何度か聞いたことがあったのですが、「参考書の方が速く読めるし、物によるけど説明も丁寧だし、、」と敬遠してきました。
今回初めてプログラミングガイドにしっかりと目を通し、「全部書いてある...。(当然)」と。
原典にあたる大切さを実感として得ることができました。
ビット演算子等まだ理解が及ばない部分も多いので、間違い等ありましたらご指摘下さい。
こういったイベントに積極的に参加する会社っていいですね!(宣伝)