Last active
April 2, 2018 02:38
-
-
Save creaaa/97f834fb7a5288d5f7d9f25434be31da 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
let a: Int? = 42 | |
let b = a as! Int // 成功するか??? => した | |
print(b) // 42 | |
// コンパイラの解決パターン | |
Int to Optional<Int> is [value-to-optional] | |
// つまりこれ...暗黙の型変換「じゃな」くない...??? | |
// だって、元の情報、失われてないのだから... | |
// ただし、ジェネリクス型が絡んできてるので、また事情が違うのかもしれない... | |
// とりあえず、俺はひとまず 暗黙の型変換「じゃない」って立場をとっとくわ。 | |
// すなわちこれは、「ただの親子関係」、Int が 親クラスたる Int? として振る舞ってるだけ、 | |
// って考えといたほうが一貫性ある。いまんとこ。 | |
// ...待って、前言撤回... | |
let c = Optional.some(42) | |
let d = c as! Int // ...え??? 成功する... | |
print(d) // 42. なんで... | |
// コンパイラの解決パターン | |
Optional<Int> to Optional<Int> is [deep equality] | |
// もちろん、パターンマッチも行ける...DATO..... | |
switch c { | |
case let no as Int: | |
print(no.description) // マッチ | |
default: break | |
} | |
☆ 4/1時点での結論としては、 | |
「サブタイピングは実行時の型強制に置き換えられる」 | |
from https://qiita.com/ukitaka/items/8bcff4348c79d820ba32 | |
俺なりの理解だと、インスタンスは、親クラス型の変数に格納されると、『半分アップキャストされ、半分は元の型のまま、みたいな形』になり、 | |
親クラスと子クラスの狭間で、どちらでも取れるようなふるまいをする。 | |
だから、親クラスの型の変数に代入できるし、 | |
だから、as!とかすると元の子クラスに戻ることに成功するし、上のように case as で子クラスの型にマッチする。 | |
// let f: Int = c // ただし、もちろん相変わらずこれはできない... | |
// これは通常の親-子クラスの振る舞いと同じなので全く正常であるし、そもそもこれできたらnull安全が崩壊する | |
// 謎深まった。。。 | |
/* | |
2/27時点での結論。 | |
1. やっぱりこれは、暗黙の型変換 「ではない」。インスタンスは依然 Int? 型である。 | |
2. ただし、「"ある程度"Int型としても振る舞うことができる」 Int? 型 である。 | |
【ある程度】の範囲 | |
○ => as? / as! / キャストパターンによるパターンマッチ | |
...むしろ、let a: Int? = 42 のときではなく、 | |
(ここは"本当に何も"起こってない。ただの親クラスへの代入) | |
let c = Optional.some(42) のときに、 | |
Int への暗黙の型変換が行われてる、と考えたほうが自然じゃね??? | |
fだって、c is Int が true になるし。 | |
いきなり、親クラスが子クラスとみなされることは通常ありえへんぞ。 | |
*/ | |
// 続報が入り次第追って報告する。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment