1. KentaKudo

    Posted

    KentaKudo
Changes in title
+Swift演算子まとめ
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,468 @@
+Swiftの演算子、まとめました。
+
+# 演算子一覧
+Prefix演算子
+
+| 演算子 | 作用 |
+|:----------:|:-----------:|
+| ++ | 1加算 |
+| -- | 1減算 |
+| ! | 論理NOT |
+| ~ | ビットNOT |
+| + (単項) | +符号 |
+| - (単項) | -符号 |
+
+Postfix演算子
+
+| 演算子 | 説明 |
+|:----------:|:-----------:|
+| ++ | 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 |
+
+# 用語
+
+**単項演算子(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は値を返した後に演算を行う。
+
+```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: Int) -> 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初投稿でした!楽しかったです!
+
+"プログラミングガイドを読むべし"みたいな話を何度か聞いたことがあったのですが、「参考書の方が速く読めるし、物によるけど説明も丁寧だし、、」と敬遠してきました。
+今回初めてプログラミングガイドにしっかりと目を通し、「全部書いてある...。(当然)」と。
+原典にあたる大切さを実感として得ることができました。
+
+ビット演算子等まだ理解が及ばない部分も多いので、間違い等ありましたらご指摘下さい。
+
+
+こういったイベントに積極的に参加する会社っていいですね!(宣伝)