1. BlueRayi
Changes in body
Source | HTML | Preview
@@ -1,468 +1,471 @@
Swiftの演算子、まとめました。
# 演算子一覧
Prefix演算子
| 演算子 | 作用 |
|:----------:|:-----------:|
-| ++ | 1加算 |
-| -- | 1減算 |
+| ++ | 1加算 |
+| -- | 1減算 |
| ! | 論理NOT |
| ~ | ビットNOT |
| + (単項) | +符号 |
| - (単項) | -符号 |
Postfix演算子
| 演算子 | 説明 |
|:----------:|:-----------:|
-| ++ | 1加算 |
-| -- | 1減算 |
+| ++ | 1加算 |
+| -- | 1減算 |
Infix演算子
| 演算子 | 説明 | 結合律 | 優先順位 |
|:-------------:|:---------------:|:-----:|:-------:|
| << | 左ビットシフト | 無結合 | 160 |
| >> | 右ビットシフト | 無結合 | 160 |
| * | 乗算 | 左結合 | 160 |
| / | 除算 | 左結合 | 160 |
| % | 剰余 | 左結合 | 160 |
| &* | オーバーフロー乗算 | 左結合 | 160 |
| & | ビットAND | 左結合 | 160 |
| + | 加算 | 左結合 | 140 |
| - | 減算 | 左結合 | 140 |
| &+ | オーバーフロー加算 | 左結合 | 140 |
| &- | オーバーフロー減算 | 左結合 | 140 |
| &#124; | ビット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 |
| &#124;&#124; | 論理OR | 左結合 | 110 |
| ?: | 三項条件 | 右結合 | 100 |
| = | 代入 | 右結合 | 90 |
| *= | 乗算と代入 | 右結合 | 90 |
| /= | 徐算と代入 | 右結合 | 90 |
| %= | 剰余と代入 | 右結合 | 90 |
| += | 加算と代入 | 右結合 | 90 |
| -= | 減算と代入 | 右結合 | 90 |
| <<= | 左ビットシフトと代入 | 右結合 | 90 |
| >>= | 右ビットシフトと代入 | 右結合 | 90 |
| &= | ビットANDと代入 | 右結合 | 90 |
| &#124;= | ビットORと代入 | 右結合 | 90 |
| ^= | ビットNOTと代入 | 右結合 | 90 |
| &&= | 論理ANDと代入 | 右結合 | 90 |
| &#124;&#124;= | 論理ORと代入 | 右結合 | 90 |
+※…++演算子、--演算子はSwift3.0で削除された。
+
# 用語
**単項演算子(Unary)**
被演算子(Operand)が1つの演算子。
前置のもの(prefix)と後置のもの(postfix)がある。
**二項演算子(Binary)**
被演算子が2つの演算子。
被演算子の間に置かれる(infix)。
**三項演算子(Ternary)**
被演算子が3つの演算子。
?:の一つだけ(infix)。
**優先順位**
数値が大きいものほど先に演算される。
単項演算子は二項演算子よりも優先順位が高い。
**結合律**
優先順位が同じ演算子が並んだ場合は、左結合のものは左から、右結合のものは右から演算される。
(同じ優先順位で、左結合のものと右結合のものは混在しない。)
無結合の演算子が並んだ場合はエラーとなる。
```swift
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と異なり、値を返さない。
```swift
let (x, y) = (1, 2)
// x = 1, y = 2
if x = y { // 判定する値が返らない
// エラー
}
```
## 算術演算子
### +, -, *, /
Objective-Cと異なり、オーバーフローを許容しない。
```swift
var i: Int8 = 127 // Int8の最大数
i++ // エラー
```
### %
a % b は
```
a = (b * 整数) + 余り
```
と解釈される。
```swift:
-9 % 4 // (4 * -2) - 1
// -1
-9 % -4 // (-4 * 2) - 1
// -1
```
また、Float型にも適用可能。
```swift
8 % 2.5 // 0.5
```
### ++, --
それぞれ、1の加算、1の減算となる。
prefixは演算の後に値を返し、postfixは値を返した後に演算を行う。
+Swift3.0からは削除されたため、+=演算子、-=演算子などを使って代用する(ただし、これらの演算子は値を返さない)。
```swift:
var a = 0, b = 0
let c = ++a // 1
let d = b++ // 0
```
### +, - (単項)
符号を表す。
## オーバーフロー演算子
### &+, &-, &*
オーバーフローを許容する演算子。
```swift
var i: Int8 = 127 // Int8の最大数
i &+ 1 // -128: Int8の最小数
```
## 比較演算子
### ==, !=, <, >, <=, >=
それぞれ比較の結果のBool値を返す。
### ===, !==
被演算子が同じオブジェクトを参照しているかどうかを判定する。
(被演算子はクラスのオブジェクト)
## 三項条件演算子
### ?:
Swift唯一の三項演算子。
```swift
let isSelected = true
if isSelected {
print("true")
} else {
print("false")
}
// ↓同じ
isSelected ? print("true") : print("false")
```
## Nil Coalescing 演算子
### ??
a ?? b (aはオプショナル型)
aがnilのときbを返す演算子。
```swift
let integer: Int? = nil
let beta: Int = 10
alpha != nil ? alpha! : beta
// ↓同じ
alpha ?? beta
```
## パターンマッチ
### ~=
パターンマッチの結果をBool値で返す。
区間(後述)のマッチによく使われる。
```swift
0...100 ~= 15 // true
```
switch文のcase分岐の際、内部で使われている演算子。
## 区間演算子
両側が整数 → Range<Int>型:for-inに使える。
片側or両側が浮動小数点数 → ClosedInterval型(閉区間)、HalfOpenInterval型(半開区間):for-inに使えない。
### ...
閉区間:右側の数が含まれる区間。
```swift
0...100 ~= 100 // true
```
### ..<
半開区間:右側の数を含まない区間。
```swift
0..<100 ~= 100 // false
```
## 論理演算子(Logical Operators)
Swiftで論理演算子の被演算子となるはBool型のみ。
### !
論理NOT
```swift:
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演算。
```swift:
let bit: UInt8 = 0b00001111 // = 15
// ↓
~bit // 0b11110000 = 240
```
(0bは2進数を表すリテラル。)
### &
ビットAND
それぞれの桁同士にAND演算。
```swift:
let bit1: UInt8 = 0b11111100 // = 252
let bit2: UInt8 = 0b11110000 // = 240
// ↓
bit1 & bit2 // 0b11110000 = 240
```
### |
ビットOR
それぞれの桁同士にOR演算。
```swift:
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)
```swift:
let bit1: UInt8 = 0b11111100 // = 252
let bit2: UInt8 = 0b11110000 // = 240
// ↓
bit1 ^ bit2 // 0b00001100 = 12
```
### <<, >>
ビットシフト演算子
それぞれの桁を右または左に指定した値シフトする。
シフトにより空いた桁を埋める値は、整数型が符号ありか符号なしかで異なる。
+ 符号なし整数(Unsigned Int)
シフトにより空いた桁を0で埋める
```swift
let unsignedInt: UInt8 = 0b11111111 // 255
// ↓
unsignedInt << 4 // 0b11110000 = 240
unsignedInt >> 4 // 0b00001111 = 15
```
+ 符号あり整数(Signed Int)
最上位の桁は符号ビット(the sign bit)といい、0で正、1で負を表す。
符号あり整数の場合、シフトにより空いた桁は符号ビットの値で埋められる。
```swift
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進数での表し方](http://www.geocities.jp/zaqzaqpa/2sinsuu8.htm)
## 複合代入演算子
各々の演算後に、結果を代入する演算子。
### +=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^=, &&=, ||=
```swift
var int: Int = 3
int += 5
// ↓同じ
int = int + 5
var bit: UInt8 = 0b11110000 // 240
bit <<= 4 // 0b00000000 = 0
// ↓同じ
bit = bit << 4
```
## 型チェック、型キャスト
### is
型チェック。
左項のオブジェクトが右項の型に一致すればtrue、異なればfalseを返す。
```swift
let str: Any = "string"
str is String // true
```
### as, as? as!
ダウンキャストを行う。
```swift
let str: String = "string"
str as NSString
```
as!はダウンキャストに失敗した場合、クラッシュする。
as?はダウンキャストに失敗した場合、nilが入る。
```swift
let str: Any = "string"
str as! Int // 実行時エラー
str as? Int // nil
```
# 演算子オーバーロード
既存の演算子の書き換え・定義されてない型への定義。
オーバーロードとカスタム演算子(後述)の導入が可能なのは単項演算子と二項演算子のみ。
書き換えは用法と用量を守りましょう。
```swift
// * を + に書き換え
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"
```
# カスタム演算子
新たに演算子を定義。
```swift
// 累乗を計算する演算子を定義
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
# おわりに
Quite初投稿でした!楽しかったです!
"プログラミングガイドを読むべし"みたいな話を何度か聞いたことがあったのですが、「参考書の方が速く読めるし、物によるけど説明も丁寧だし、、」と敬遠してきました。
今回初めてプログラミングガイドにしっかりと目を通し、「全部書いてある...。(当然)」と。
原典にあたる大切さを実感として得ることができました。
ビット演算子等まだ理解が及ばない部分も多いので、間違い等ありましたらご指摘下さい。
こういったイベントに積極的に参加する会社っていいですね!(宣伝)