В Swift 2.x, у меня были миленькая установка, которая позволила мне хранить и извлекать словарные значения с помощью членов перечислений:Swift 3 Generic расширение Аргументов
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
, а общие Key
и Value
аргументы все еще присутствуют в Generic Argument Clause структуры Dictionary
, поэтому я не уверен, в чем проблема.
Нужно ли переписать статью where
, чтобы соответствовать новой грамматике Swift 3, о которой я не знаю? Или ... можно ли больше не обращаться к общим типам заполнителей в расширениях?
Я просто не знаю, что делать!
В моем проекте осталось всего 28 ошибок миграции. Я настолько близок к тому, что фактически использовал Swift 3, поэтому мне бы понравились любые указатели (если они не Unsafe
и/или Raw
).
Спасибо!
Это не должно работал в Swift 2 ... ... К сожалению, общий параметр конкретного типа не может быть ограничен конкретным типом. –
@TimVermeulen Хотя я согласен с вами, я прибегал к этой «хакерской» работе в нескольких местах, и она все еще работает в других расширениях (не цитируйте меня). Как можно переписывать его, чтобы он работал, оставаясь «родовым»? Я помню, как пробовал всевозможные забавные вещи, например, если 'String' соответствовал некоторому пустым протоколу StringLike и использовал это как общее ограничение, но в итоге он не работал по той или иной причине. Думаю, моя проблема сводится к «правильному» внедрению ориентированных на протокол шаблонов проектирования. –
Связанный (и возможный дубликат?): [Подстрочный индекс: доступ к значениям словаря с перечислением String] (http://stackoverflow.com/questions/39499137/subscript-access-my-dictionary-values-with-a-string- перечисление) – Hamish