Ваше предположение, что проблема связана с типами смешивания в вашем словаре, абсолютно правильна. «_
», который вы видите, относится к неизвестному предполагаемому типу. Swift не может понять, какой тип stuff
находится в вашем коде, поэтому вам нужно сделать все более понятным для него. Быстрый и грязный способ справиться с этим - утверждать, что ваш словарь содержит что-либо.
> let x = ["one": 1, "two": "2"]
repl.swift:7:27: error: '_' is not convertible to 'UnicodeScalarLiteralConvertible'
> let x : [String: Any] = ["one": 1, "two": "2"]
x: [String : Any] = 2 key/value pairs { ... }
Причина, по которой Свифт не делает это для вас, что Свифт никогда не будет вывести Any
типа, и по уважительной причине. Если это произойдет, это приведет к появлению большинства ошибок типа. Поэтому вы можете заставить Swift использовать тип Any
, если вы хотите ...
Но вы, вероятно, не должны. Если вы используете Any
, вы теряете довольно много типов безопасности. Лучший способ справиться с этим - создать enum
для хранения различных типов. Таким образом вы можете ограничить свой список только тем, что вы ожидаете. Если мы определим перечисление вроде следующего:
enum Thing {
case AnInt(Int);
case AString(String);
}
Мы можем определить список, только немного более многословным, и Swift будет иметь возможность правильно определить тип всего выражения, и дают нам большую безопасность.
> let x = ["one": Thing.AnInt(1), "two": Thing.AString("2")]
x: [String : Thing] = 2 key/value pairs { ... }
Ваш пример может использовать перечисление как этого
enum ListOrString {
case AString(String);
case AList([String]);
}
И вы могли бы написать свой словарь как это:
var stuff = [
[
"id" : ListOrString.AString("A9AD6748-62A1-47E9-B0F7-2CF9B9C138EE"),
"label" : .AString("My Cool Label"),
"things" : .AList([
"1st string",
"2nd string",
"3rd string"
])
],
[
"id" : .AString("9C7882A7-E40C-421F-BEDB-8C0249A768E3"),
"label" : .AString("Another Cool Label"),
"things" : .AList([
"4th string",
"5th string",
"6th string"
])
]
]
Обратите внимание, что у вас есть только указать ListOrString
один раз, и что каждый раз вы можете просто использовать голый .
. Набрав это мой Swift РЕПЛ правильно выводит тип как
stuff: [[String : ListOrString]]
В этом контексте '_' относится к неизвестному выведенному типу. – porglezomp