What's .self, .Type and .Protocol? Understanding Swift Metatypes

什么是Metatypes?

Metatypes 是類型的類型,比如 3 是 Int 類型的實例,可以說 Int 是3的類型;那么Int的類型是啥的?Int的類型就可以稱為元類型;

struct TestStruck {
    static let show = "show"
    
    func printName() { }
}
let test: TestStruck = TestStruck()

test: TestStruck = TestStruck() 中,我們可以說 test 是 TestStruck 的實例,而 test 的類型是 TestStruck;

我們可以通過 test 調(diào)用 printName() 方法,但是我們不能通過 test 調(diào)用 show 屬性;那么我們怎樣調(diào)用show 屬性呢?

我們可以通過 TestStruck.show 方式調(diào)用,同樣的我們也可以通過 type(of: test) 方式調(diào)用;

我們通過 type(of: ) 將實例轉(zhuǎn)換為可以調(diào)用對應(yīng)類的所以類屬性及方法的元類型;

let testType = type(of: test)
testType.show

這個時候我們可以查看一下 testType 的類型為TestStruck.Type;TestStruck.Type 就是 TestStruck 的元類型;

我們定義可以包括class、struct、enum、Protocol在內(nèi)的任何類型的元類型,只需要在對應(yīng)的類型名字后面調(diào)用.type,即 TestStruck.Type

type(of:) Dynamic Metatypes vs .self Static Metatypes

TestStruck.Type是元類型,那么這個類型的值什么呢?

比如String類型他的值是"string";我們可以通過 .self獲得.Type類型的值,如TestStruck.Type 類型的值為 TestStruck.self;

舉例

typealias AnyClass = AnyObject.Type
UITableView 中注冊cell的方法 register(AnyClass?, forCellReuseIdentifier: String)
tableView.register(MyTableViewCell.self, forReuseIdentifier: "myCell")

蘋果稱.selfstatic metatype,表示對象在編譯時的類型;

type(of)dynamic metatype,代表在運行時對象真正的元類型;

let myNum: Any = 1 // Compile time type of myNum is Any, but the runtime type is Int.
type(of: myNum) // Int.type

Protocol Metatypes

前面說到的這些概念都適用Protocol,但是如果我們寫下面的代碼會報錯

protocol MyProtocol {}
let metatype: MyProtocol.Type = MyProtocol.self  // error

這是在 Protocol 的上下文中,MyProtocol.Type并不代表 Protocol 自身的元類型,而是代表遵守這個協(xié)議的任何類型的元類型,蘋果將其稱為existential metatype(存在性元類型);

protocol MyProtocol {}
struct MyType: MyProtocol {}
let metatype: MyProtocol.Type = MyType.self // Now works!

上面的代碼是正確的,這個時候 metatype 只是去訪問 MyProtocol 的類方法和屬性,但是實際的調(diào)用是MyType中的實現(xiàn);

想要正確的獲得Protocol的元類型可以通過 .protocol,和前面提到的.Type是一樣的;

let protMetatype: MyProtocol.Protocol = MyProtocol.self

其實這個時候我們并不能通過 protMetatype 做什么,大概只能做簡單的 protMetatype is MyProtocol.Protocol;

資料引用

Apple Types

blog

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容