2016-05-19 60 views
1

我想知道是否可以動態獲取Swift類型。例如,假設我們有以下的嵌套結構:是否有可能從字符串中獲取Swift類型?

struct Constants { 

    struct BlockA { 
    static let kFirstConstantA = "firstConstantA" 
    static let kSecondConstantA = "secondConstantA" 
    } 

struct BlockB {  
    static let kFirstConstantB = "firstConstantB" 
    static let kSecondConstantB = "secondConstantB" 
    } 

    struct BlockC { 
    static let kFirstConstantC = "firstConstantBC" 
    static let kSecondConstantC = "secondConstantC" 
    } 
} 

它可以從一個變量從kSeconConstantC獲得價值)。像:

let variableString = "BlockC" 
let constantValue = Constants.variableString.kSecondConstantC 

東西類似NSClassFromString,也許?

+0

值不能用作標識符,根據我的想法我認爲這是不可能的 –

+0

你可以使用像if(variableString ==「BlockC」)然後做點什麼 –

+0

謝謝你的讚揚,但背後的想法是減少碼。我更喜歡(如果存在)解決方案,而不是爲每個案例寫幾個if-else。 – RFG

回答

2

不,現在還不可能(至少作爲語言功能)。

你需要的是你自己的類型註冊表。即使是一個類型的註冊表,你將無法得到static常量,除非你有該協議:

var typeRegistry: [String: Any.Type] = [:] 

func indexType(type: Any.Type) 
{ 
    typeRegistry[String(type)] = type 
} 

protocol Foo 
{ 
    static var bar: String { get set } 
} 

struct X: Foo 
{ 
    static var bar: String = "x-bar" 
} 

struct Y: Foo 
{ 
    static var bar: String = "y-bar" 
} 

indexType(X) 
indexType(Y) 

typeRegistry // ["X": X.Type, "Y": Y.Type] 

(typeRegistry["X"] as! Foo.Type).bar // "x-bar" 
(typeRegistry["Y"] as! Foo.Type).bar // "y-bar" 

A型註冊表是一些註冊使用自定義Hashable類型(比如一個String或你的類型一個Int)。然後,您可以使用此類型註冊表來引用使用自定義標識符的註冊類型(在本例中爲String)。

因爲Any.Type本身並不是那麼有用,所以我構建了一個接口Foo,通過它我可以訪問一個靜態常量bar。因爲我知道X.TypeY.Type都符合Foo.Type,所以我強制轉換並閱讀bar屬性。

+0

酷!你能解釋一下發生了什麼? –

+0

謝謝,我會盡力按照這種方式。 – RFG

+0

這很簡潔,但請注意,如果您知道給定註冊表中的類型將始終符合給定的協議,則應該使註冊表爲[[String:Foo.Type]'以消除惡臭力向下轉換。 – Hamish

相關問題