Swift 3 通用扩展参数

标签 swift generics dictionary swift3 swift-extensions

在 Swift 2.x 中,我有一个不错的小设置,允许我使用枚举成员存储和检索字典值:

public enum UserDefaultsKey : String {
    case mainWindowFrame
    case selectedTabIndex
    case recentSearches
}

extension Dictionary where Key : String {
    public subscript(key: UserDefaultsKey) -> Value? {
        get { return self[key.rawValue] }
        set { self[key.rawValue] = newValue }
    }
}

这让我可以像这样访问值:

let dict = userDefaults.dictionaryForKey("SearchPrefs")
if let recentSearches = dict?[.recentSearches] as? [String] {
    // Populate "Recent" menu items
}

... 而不是像这样访问值:

let dict = userDefaults.dictionaryForKey("SearchPrefs")
if let recentSearches = dict?[UserDefaultsKey.recentSearches.rawValue] as? [String] {
    // Populate "Recent" menu items
}

注意:使用字符串文字从 NSUserDefaults 访问字典仅用于示例目的。我实际上不会特意为字典键使用枚举,只是使用字符串文字来访问字典本身。 :-)


无论如何,这对我的需求很有用,它使阅读和维护涉及 NSUserDefaults 的代码变得更加愉快。

然而,自从将我的项目迁移到 Swift 3 后,我收到了以下错误:

extension Dictionary where Key: String {
    public subscript(key: UserDefaultsKey) -> Value? { <---- Use of undeclared type 'Value'
                                              ~~~~~~
        get {
            return self[key.rawValue]
        }
        set {
            self[key.rawValue] = newValue
        }
    }
}

我查看了为 Dictionary 生成的 header ,通用的 KeyValue 参数仍然存在于 Generic Argument Clause 中。 Dictionary 结构,所以我不太确定问题出在哪里。

我是否需要重写 where 子句以符合一些我不知道的新 Swift 3 语法?或者……是否可以不再访问扩展中的通用占位符类型?

我只是不知道该怎么办!

我的项目只剩下 28 个迁移错误需要解决。我离实际使用 Swift 3 如此之近,所以我喜欢任何指示(只要它们不是 Unsafe 和/或 Raw)。

谢谢!

最佳答案

目前无法将具体类型的泛型参数限制为具体类型。这意味着像

extension Dictionary where Key == String

不会编译。这是泛型系统的一个限制,希望在 Swift 4 中不会成为问题。

虽然有一个解决方法,但它有点 hacky:

protocol StringConvertible {
    init(_ string: String)
}

extension String: StringConvertible {}

extension Dictionary where Key: StringConvertible {

    subscript(key: UserDefaultsKey) -> Value? {
        get { return self[Key(key.rawValue)] }
        set { self[Key(key.rawValue)] = newValue }
    }

}

关于Swift 3 通用扩展参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39735753/

相关文章:

java - 什么是原始类型,为什么我们不应该使用它呢?

arrays - 戈朗 : multidimensional string array instead of maps

objective-c - 有没有办法以编程方式访问 OSX 系统词典?

c# - 通用小数不能从 double 转换

java - 具有不同具体类型作为方法参数的接口(interface)实现

python - 带有 MultiIndex 的 DataFrame

ios - 无法向我的应用程序添加新的 iOS 包标识符 - LinkedIn

swift - 从 Parse.com 查询到 UICollectionView

swift - Snapkit 和 TableView 中的多个自定义单元格

ios swift核心图形-字符串颠倒