我想实现一些代码,以便我可以调用类似的东西:
NSUserDefaults("key1", "value1")
let s = NSUserDefaults("key1") // "value1" expected
NSUserDefaults("key2", 2.01)
let s = NSUserDefaults("key2") // 2.01 expected
我在概念中有一些代码如下,但显然它不会起作用。所以我的问题是,不是像class func bool(key: String, _ v: Bool? = nil) -> Bool?
那样编写一系列函数,而是有什么方法可以利用通用的优势吗?
extension NSUserDefaults {
class func object<T: AnyObject>(key: String, _ v: T? = nil) -> T? {
if let obj: T = v {
NSUserDefaults.standardUserDefaults().setObject(obj, forKey: key)
NSUserDefaults.standardUserDefaults().synchronize()
} else {
return NSUserDefaults.standardUserDefaults().objectForKey(key) as T?
}
return v
}
}
答案 0 :(得分:1)
你的语法很糟糕。这行无法按照书面形式工作:
let s = NSUserDefaults("key1") // "value1" expected
Swift必须在编译时为s
选择一个类型,而不是运行时。因此,此处唯一可以分配的类型是Any
(如果您想要返回AnyObject
,则Double
甚至Double
都不够广泛,因为AnyObject
不是let s : Any = ...
)。
这意味着你必须明确地调出Any
(因为Swift明智地不会让你隐含地创建Any
),然后你最终会找到objectForKey()
你必须以某种方式进行打字检查。当你完成后,你将完全转到defaults["key1"]
。
即使您可以使用此语法,也不应该尝试重载单个函数语法来执行相反的操作。这非常令人困惑。如果你要构建这样的扩展,你应该把它作为下标。这样你就可以说defaults["key2"] = 2.01
和AnyObject?
。这可能是可以构建的(尽管仍然会有处理{{1}}所需的类型注释问题。)