Быстрая ошибка словаря?
Итак, я начал проект в Swift, и я пришел к этой проблеме:
этот код работает:
var dictionary = ["a":"valueOfA","b":"valueOfB","c":"valueOfC"]
println(dictionary)
dictionary["c"] = "newValOfC"
println(dictionary)
и это не так:
var dictionary = [:]
dictionary = ["a":"valueOfA","b":"valueOfB","c":"valueOfC"]
println(dictionary)
dictionary["c"] = "newValOfC"
println(dictionary)
Дает ошибку:
Playground execution failed: error: <REPL>:35:17: error: cannot assign to the result of this expression
dictionary["c"] = "newValC"
~~~~~~~~~~~~~~~ ^
Обратите внимание, что это не постоянное значение
Так почему же строка
dictionary = ["a":"valueOfA","b":"valueOfB","c":"valueOfC"]
введите ошибку?
Ответы
Ответ 1
Поскольку контекст не предоставляет достаточной информации для вывода типа, вам нужно явно называть его как словарь, иначе swift предполагает, что это NSDictionary
(я не понимаю, почему. лучше совместимость с OBJC):
Работает следующий код:
// Playground
import UIKit
var str:NSString = "Hello, playground"
var d0 = [:]
var d1: Dictionary = [:]
d0.setValue(UIWebView(), forKey: "asdf")
d1["asdf"] = 1
d1["qwer"] = "qwer"
Ответ 2
Хорошо, я нашел его, проблема в том, что, инициализируя пустой словарь, вывод типа немного сумасшедший.
Вам понадобится этот код:
var dictionary = Dictionary<String, String>()
вместо
var dictionary = [:]
но это все еще не объясняет, почему строка
dictionary = ["a":"valueOfA","b":"valueOfB","c":"valueOfC"]
не дает ошибки
Ответ 3
И ссылаясь на Руководство по языку Swift,
dictionary = [:]
Синтаксис правильный, если контекст уже предоставляет информацию о типе.
Ответ 4
Большая разница в том, что
var dictionary = [:]
не дает возможности компилятору вывести правильный тип, тогда как
var dictionary = ["a":"valueOfA","b":"valueOfB","c":"valueOfC"]
делает.
На самом деле, похоже, что первая строка создает экземпляр __NSDictionaryI
, тогда как второй создает Dictionary<String,String
, как ожидалось.
Из книги Swift Programming Language
Если контекст уже предоставляет информацию о типе, создайте пустой словарь с пустым словарным литералом, который написан как [:] (двоеточие внутри пары квадратных скобок):
что означает, что первая строка неоднозначна.
Ответ 5
Синтаксис [:]
работает только в том случае, если в текущем контексте достаточно информации, чтобы иметь возможность выводить те типы. Вот несколько способов, которыми известен контекст...
Как уже упоминалось, приведенный ниже код работает, поскольку можно предположить, что ключи и значения являются строками:
var dictionary = [ "a" : "valueOfA" , "b" : "valueOfB" , "c" : "valueOfC" ]
Словарь, переданный в функцию, имеет известный контекст:
func dictionaryFunc(var dictionary : Dictionary<String, String>) {
// Do stuff with the dictionary
}
В обоих случаях теперь известны ключи/значения для словаря, поэтому вы можете сделать это для создания нового словаря с тем же именем переменной...
dictionary = [:]
В первом случае, если вы использовали синтаксис [:]
после объявления, вы бы удалили содержимое исходного словаря. Во втором случае словари копируются, когда они передаются в функции, поэтому использование [:]
будет только стирать копию.
Ответ 6
В Swift 2.0 я использую это:
var dictionary = [String:String]()
dictionary["key1"] = "value1"