Last active
February 27, 2018 22:19
-
-
Save creaaa/91118fdd2ca08ff782359157bd0fc3e9 to your computer and use it in GitHub Desktop.
気をつけて
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Animal {} | |
class Cat: Animal { | |
func pero() {} | |
} | |
let animals: [Animal] = [Cat()] | |
/* これ、ふつーにいけると思いきや。。。アウト!! | |
まぁでも、そらそうか。 | |
すなわち... | |
「一旦親クラスの変数に格納してしまうと、インスタンスの型情報は失われる」 | |
*/ | |
// let cat: Cat = animals[0] // コンパイルエラー! | |
let cat = animals[0] // これは通る。型は Animal に推論される。 | |
// 一旦、インスタンスの型情報が失われてしまったら、 | |
// as? か as! か キャストパターンのパターンマッチ に 賭けてみるしかないのだ。 | |
// let cat2 = animals[0] as! Cat ← まぁ今回はそりゃ成功するけど、バリバリ型安全から外れてる | |
/* | |
結論 | |
インスタンスを、親クラスの変数に格納し、一旦親クラスとして扱ってしまうと、 | |
インスタンスの型情報は失われる。(内部ではちゃんと残ってるから、↓のようにas! できるんだが) | |
復活させるには、as? / as! / パターンマッチ に賭けてみるしかなくなるので、 | |
型安全からは少し離れた気になってくるので注意しる。 | |
*/ | |
// 型パターン の if case, めっちゃ書きにくいww | |
// = の 左側は case ○○, 右側は switch ×× が来る、 | |
// という一貫性に基づいているので我慢しろ!! | |
if case let cat as Cat = animals[0] { | |
print(cat.pero()) // cat は Cat型として扱えるため、Cat#メソッド が呼べる | |
} | |
// 次のgist は これを踏まえ、 T と T? の関係に迫る。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment