Swift中的泛型类型作为返回值

时间:2015-03-18 01:33:55

标签: swift generics

我想实现一些代码,以便我可以调用类似的东西:

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
    }
}

1 个答案:

答案 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.01AnyObject?。这可能是可以构建的(尽管仍然会有处理{{1}}所需的类型注释问题。)

相关问题