我用swift在xcode 7.3.1的操场上玩弄。我对swift中的类型转换有点困惑。
所以,这是我尝试的一些代码。
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
我在评论中显示了操场上的输出。在这里,您可以看到每一行的类型。
现在根据apple的文档,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
?
所以,我的问题是,当我将一些派生类(Movie
)类型转换为基类(MediaType
)时,转换后的类型不应该是基类(MediaType
)?
答案 0 :(得分:3)
dynamicType
告诉你对象的基础类型是什么。它并没有告诉你当前引用该对象的var
类型是什么。
例如:
let a: Any = 3
a.dynamicType // Int.Type
当然,Swift会跟踪这些基础类型,这些类型允许您稍后向下转换 MediaItem
到Movie
(如果它真的是这样的话) )。
当你这样做时,你会感到困惑:
(movieItem as? MediaItem).dynamicType //Optional<MediaItem>.Type
可选是它自己的类型。它是一个包含两个值的枚举:.None
和.Some(T)
。 .Some
值具有关联值,该值具有自己的动态类型。在您的示例中,当您要求dynamicType
时,它返回可选的基础类型,其中是 Optional<MediaItem>.Type
。它没有告诉您与 Optional 相关联的值的动态类型是什么。
考虑一下:
let x = (movieItem as? MediaItem)
x.dynamicType // Optional<MediaItem>.Type
x!.dynamicType // Movie.Type