2016-05-19 59 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

相关问题