2016-06-23 4 views
2

私はxcode 7.3.1の遊び場ですばやくおしゃべりしていました。私は、ちょっとしたタイプキャスティングについて、ちょっと混乱しています。すぐにタイプキャストすることについての混乱

ここでは、私が試したコードの一部です。

class MediaItem { 
    var name: String 
    init(name: String) { 
     self.name = name 
    } 
} 

class Movie: MediaItem { 
    var director: String 
    init(name: String, director: String) { 
     self.director = director 
     super.init(name: name) 
    } 
} 

class Song: MediaItem { 
    var artist: String 
    init(name: String, artist: String) { 
     self.artist = artist 
     super.init(name: name) 
    } 
} 

var movieItem = Movie(name: "GOT", director: "RRMartin") 

movieItem.dynamicType     //Movie.Type 
(movieItem as? MediaItem).dynamicType //Optional<MediaItem>.Type 
var someItm = movieItem as! MediaItem //Movie 
someItm.dynamicType     //Movie.Type 

私はコメントに遊び場からの出力を示しました。ここでは、各行のタイプを見ることができます。

リンゴの文書に従うThe conditional form, as?, returns an optional value of the type you are trying to downcast to.ドキュメントごとに、私はMediaItemにダウンキャストしようとしています。オプションのタイプとしてMediaItemを取得しています。

しかし、force unwrap(つまりas!)を使用すると、返されるタイプはMovieです。しかし、私はそれがMediaItemになりたかった。

また、タイプは実際に変更されています。一部のデータは実際に切り捨てられます。ムービーにあるdirectorプロパティにアクセスしようとしたときにアクセスできませんでした。私がそれを落としたので。

したがって、タイプがダウンキャストの場合、返されるタイプはMovieですか? MediaTypeではありませんか?

私は、基本クラス(MediaType)に、いくつかの派生クラス(Movie)のキャストを入力するときだから、私の質問はこれで、変換後のタイプは、基本クラス(MediaType)すべきではありませんか?

+0

はこのことを考えてみましょう。実際に何をしようとしているのか説明できますか?オブジェクトが「ムービー」であることを知っているときに、なぜ「MediaItem」が必要だと思いますか?最高の見積もりはWWDCです。「あなたがSwiftのダウンキャストタイプを試していたら、タイプシステムと戦っていて、あなたが逃しているはるかに良いアプローチがある」 – Fogmeister

+0

@Fogmeister、実際には、 。私はなぜこれが起こっているのか知りたい。同じコンテキストではないかもしれませんが、文字列をIntegerに変換したいとします。タイプは整数でなければなりませんか?文字列ではありません。 –

+0

その特定の場合、いいえ、 'String'から' Int'にキャストするべきではありません。 'String'を受け入れる' Int'でfusingを使うべきです。 'let int = Int(" 123 "){...}'ここでダウンキャストしてはいけません。一般的にスウィフトにはこのようなダウンキャスティングが必要な理由はありません。 – Fogmeister

答えて

3

dynamicTypeは、オブジェクトの基本的なタイプを示します。そのオブジェクトを現在参照しているタイプがvarであるかどうかはわかりません。例えば

let a: Any = 3 
a.dynamicType // Int.Type 

スウィフトは、当然のことながら、(それはそれが本当に何であるかである場合)MovieからMediaItemあなたはに後でダウンキャストできますものですこれらの基礎となるの種類を追跡します。あなたがやったとき

あなたのために混乱が来た:

(movieItem as? MediaItem).dynamicType //Optional<MediaItem>.Type 

オプションは、それ自身のタイプです。 2つの値:.None.Some(T)の列挙です。 .Someの値には、独自の動的タイプを持つ関連値があります。あなたの例では、dynamicTypeを尋ねたときに、オプションの の基になるタイプを返しました。Optional<MediaItem>.Typeです。それは、それに関連付けられている値の動的タイプがの任意のであるかどうかを教えてくれませんでした。これは非常にXYの問題のように聞こえる

let x = (movieItem as? MediaItem) 
x.dynamicType // Optional<MediaItem>.Type 
x!.dynamicType // Movie.Type