Arhn - архитектура программирования

Общий словарь в Swift

У меня есть несколько структур Foo, Bar, Baz, и я использую приведенную ниже функцию для чтения plist в словарь [String: Foo]. И у меня есть метод, который создает словарь [String: Bar] и т. д. Все это работает хорошо.

func loadFoo() -> [String : Foo]? {
    guard
       let path = Bundle.main.path(forResource: "foo", ofType: "plist"),
       let plistDict = NSDictionary(contentsOfFile: path) as? [String : AnyObject]
       else { return nil }

    var dict = [String : Foo]()

    for (key, f) in plistDict {
       if let info = f as? [String : AnyObject] {
           let foo = Foo(symbol: key, info: info)
           dict[key] = foo
        }
    }

    return dict
} 

Конечно, это кричит «используйте дженерики», но я пока не смог заставить его работать. Например, я заменил Foo на <A> или A, но получил кучу ошибок компилятора (сейчас я далеко от своего Mac, поэтому не могу воспроизвести здесь ошибки).

Любые предложения, как решить эту проблему?

13.09.2016

  • Что такое переменная pList? 13.09.2016
  • Список свойств в Xcode; О, и опечатка, исправил. 13.09.2016

Ответы:


1
  • Создайте протокол, которому должны соответствовать все общие структуры, реализуя метод инициализации init(symbol:info:).

    protocol Fooable {
      init(symbol: String, info: [String : AnyObject])
    }
    
  • Сделайте так, чтобы все ваши структуры приняли этот протокол

    struct Baz : Fooable { ...
    
  • Теперь вы можете сделать метод загрузки универсальным, ограничив тип до Fooable.

    func loadFoo<T:Fooable>() -> [String : T]? {
      guard
        let path = Bundle.main.path(forResource: "foo", ofType: "plist"),
        let plistDict = NSDictionary(contentsOfFile: path) as? [String : AnyObject]
        else { return nil }
    
      var dict = [String : T]()
    
      for (key, f) in plistDict {
        if let info = f as? [String : AnyObject] {
          let foo = T(symbol: key, info: info)
          dict[key] = foo
        }
      }
    
      return dict
    }
    
  • и назовите его с

    let bazObject : [String : Baz]? = loadFoo()
    

    Этот синтаксис для аннотирования типа передает Baz в качестве универсального параметра.

13.09.2016
  • Так как мне это назвать? myFooDict = loadFoo() не работает (unresolved identifier loadFoo). 14.09.2016
  • Вам нужно передать структуру как общий параметр. Предполагая, что вы используете структуру Baz, напишите myFooDict = loadFoo<Baz>() 14.09.2016
  • Хм, я все еще получаю ту же ошибку. Где проживает loadFoo? Я попробовал это как расширение Loadable и получил указанную выше ошибку. Если я перенесу его из Loadable, ошибка будет: Cannot explicitly specialize a generic function и While parsing this '<' as a type parameter bracket. 14.09.2016
  • Извините, мой плохой, в этом случае синтаксис отличается, я обновил ответ 14.09.2016
  • Хорошо, теперь я получаю эту ошибку: Generic parameter 'T' could not be inferred и `При вызове функции 'loadFoo' 14.09.2016
  • Код должен работать. Я проверил это на детской площадке. 15.09.2016
  • Боюсь, нет, я тестировал в Swift 2. Действительно, это не работает в Swift 3, но я понятия не имею (пока), почему. 15.09.2016
  • Ах, мой плохой, я должен был прояснить это, я изменю тег для вопроса и поищу решение. 15.09.2016
  • Понятно. Когда я тестировал его в Swift 3, я забыл сделать так, чтобы пользовательская структура принимала Fooable -> struct Baz : Fooable { ... . Сообщение об ошибке может ввести в заблуждение. 15.09.2016
  • Просто для протокола, это та же причина, по которой я тоже получил ошибку. 16.09.2016
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..