Способ объявления типа словаря Swift со многими типами в нем, включая встроенные словари - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть struct, который я инициализирую, со словарем. Значения в этом словаре бывают разных типов: String, Int и Dictionary. Этот встроенный словарь также имеет много разных типов (String, Int, Bool, Array и Dictionary). Я знаю, это беспорядок. Итак, я пытаюсь найти правильный синтаксис для инициализатора этого struct, который принимает в качестве входных данных этот большой словарь.

Я пробовал это, но он не удовлетворяет большинству моих элементов.

init(dictionary: [AnyHashable: [AnyHashable: [AnyHashable: Any]]){
...
}

Например, при попытке доступа к String на первом уровне словаря компилятор ожидает объект типа [AnyHashable: [AnyHashable: Any]].

Существует ли общий способ объявления типа этот словарь в этом инициализаторе? Я хочу иметь возможность доступа к значениям и инициализировать переменные с ними или использовать эти значения в качестве словарей. Есть ли способ сделать это в Swift?

Дополнительная информация: я извлекаю информацию из моей БД FireStore, и именно поэтому у меня есть этот многоуровневый словарь. Документы FireStore могут обрабатывать много разных уровней информации, и мне пришлось заполнить мой для целей проектирования.

Спасибо!

1 Ответ

0 голосов
/ 21 апреля 2020

Например, при попытке доступа к String на первом уровне словаря компилятор ожидает объект типа [String: [String: Any]].

Действительно, потому что при записи dictionary: [String: [String: [String: Any]], вы дали гарантию компилятору, что значения dictionary равны [String: [String: Any]].

Если вы хотите, чтобы ваш словарь мог содержать много разных типов во время выполнения, вам нужно дать его тип stati c, который является супертипом (протокол или суперкласс) всех типов, которые вы хотите использовать. Есть два способа использования таких значений:

  1. Вы делаете протокол или суперкласс содержа функции (и свойства, индексы и т. Д. c). что вы хотите использовать. Вы можете вызывать эти функции для значений без необходимости знать конкретные типы значений. Компилятор знает, что все значения в dict будут поддерживать эти функции (благодаря тому, что он является подклассом класса или соответствует протоколу).
  2. Понижение значений (например, вы знаете, что значение для ключ "age" всегда будет Int) во время выполнения, в более конкретный тип c, который делает то, что вы хотите.

Самый общий, универсально применимый тип - Any , Но его общность заключается в том, что у него нет никаких требований, так что вы действительно ничего не можете сделать с Any, кроме как обойти его, и, в конечном счете, придется понизить его, чтобы что-то с ним сделать.

TL; DR : Вы должны использовать Any, или, возможно, какой-нибудь другой общий тип протокола или суперкласс

Еще лучше, есть куча библиотек для добавления функциональности Codable в Firebase. Я предлагаю вам использовать один из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...