Swift 3 个通用扩展参数
Swift 3 Generic Extension Arguments
在 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
生成的 headers,通用 Key
和 Value
参数仍然存在于 Generic Argument Clause 中 Dictionary
结构,所以我不太确定问题是什么。
我是否需要重写 where
子句以符合一些我不知道的新 Swift 3 语法?或者……是否可以不再访问扩展中的通用占位符类型?
我只是不知道该怎么办!
我的项目只剩下 28 个迁移错误需要解决。我非常接近实际使用 Swift 3,所以我喜欢任何指示(只要它们不是 Unsafe
and/or 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 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
生成的 headers,通用 Key
和 Value
参数仍然存在于 Generic Argument Clause 中 Dictionary
结构,所以我不太确定问题是什么。
我是否需要重写 where
子句以符合一些我不知道的新 Swift 3 语法?或者……是否可以不再访问扩展中的通用占位符类型?
我只是不知道该怎么办!
我的项目只剩下 28 个迁移错误需要解决。我非常接近实际使用 Swift 3,所以我喜欢任何指示(只要它们不是 Unsafe
and/or 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 }
}
}