Массив кортежей в Свифте
У меня есть функция:
func parseJSON3(inputData: NSData) -> NSArray {
var tempDict: (id:Int, ccomments:Int, post_date:String, post_title:String, url:String) = (id: 0, ccomments: 0, post_date: "null", post_title: "null", url: "null")
var resultArray: (id:Int, ccomments:Int, post_date:String, post_title:String, url:String)[] = []
var error: NSError?
var jsonDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(inputData, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
var firstArray = jsonDictionary.objectForKey("locations") as NSArray
for dict in firstArray {
tempDict.id = dict.valueForKey("ID") as Int
tempDict.ccomments = dict.valueForKey("ccomments") as Int
tempDict.post_date = dict.valueForKey("post_date") as String
tempDict.post_title = dict.valueForKey("post_title") as String
tempDict.url = dict.valueForKey("url") as String
resultArray.append(tempDict)
}
return resultArray
}
В строке
resultArray.append(tempDict)
У меня есть ошибка:
Отсутствует аргумент для параметра 'ccomments' в вызове
Почему? Помогите пожалуйста....
Ответы
Ответ 1
Мне кажется, что resultArray.append()
обрабатывает кортеж немного как переменный параметр и пытается расширить кортеж, чтобы он соответствовал его собственным аргументам. Он жалуется на ваш второй параметр, потому что он только ожидает его. Я не видел этого поведения для Array.append()
где-либо документально, поэтому я бы сказал, что это ошибка в Swift.
Использование оператора добавления +=
, похоже, не имеет такой проблемы:
resultArray += tempDict
Ответ 2
Итак, это довольно дико - не уверен, что я буду квалифицировать его как ошибку или как недокументированное поведение, но это определенно то, что должно быть на радаре для исправления/разъяснения!
Ситуация такова, что append
обрабатывает ваш аргумент tempDict
(который мы ожидаем быть единственным аргументом метода Array, который принимает один член и добавляет его в коллекцию) в качестве первого аргумента в сигнатуре где он ищет 5 аргументов (!), по одному для каждого члена типа Tuple, который имеет массив.
Для некоторого интересного поведения (в том числе присвоение метки единственному члену 1-членного "Tuple"?) →
см. ниже:
var arrayOne: Array<String> = []
arrayOne.append("hi")
println(arrayOne[0]) // hi
var arrayTwo: Array<(String)> = [] // where (String) is a single-member Tuple
arrayTwo.append("hi")
println(arrayTwo[0]) // hi
println(arrayTwo[0].0) // hi -> using .0 subscript to access the first member of the Tuple
// wanna see something crazy? remember arrayOne, that holds members of type String?
println(arrayOne[0].0) // hi -> this Array does not hold Tuples, but it looks like we can still treat its members like "single-member Tuples"?
var arrayThree: Array<(str: String)> = [] // members of the Array are single-member Tuples with the label 'str' for their member
arrayThree.append(str: "hi") // now we can't use append without providing the label 'str', acting as what looks like an argument label?
var byeString = "bye"
var byeTuple = ("bye")
arrayThree += byeString // += doesn't care about the label, and will take either a String or a single-member Tuple holding a String
arrayThree += byeTuple
println(arrayThree[0]) // hi
println(arrayThree[0].0) // hi
println(arrayThree[0].str) // hi -> accessing the single member of the Tuple by its label
... поэтому в вашем случае, когда вы видите ошибку с append
, что она хочет, вам нужно сделать (используя метки, которые вы использовали для объявления Tuple, как что-то похожее на ярлыки аргументов):
var resultArray: (id:Int, ccomments:Int, post_date:String, post_title:String, url:String)[] = []
...
resultArray.append(id: someIntValue, ccomments: someOtherIntValue, post_date: someStringValue, post_title: someOtherStringValue, url: someAnotherStringValue)
... и, конечно, как обсуждалось, вы можете избежать этого, просто используя +=
вместо
Сумасшедший! может быть по дизайну, чтобы служить какой-то цели, может быть следствием наследования протокола, которое не предназначалось для этого эффекта... было бы интересно узнать ответ!
Ответ 3
resultArray.append()
кажется, принимает tempDict
как первый элемент кортежа (id
).
Изменение его на:
resultArray += tempDict
похоже, компилируется и работает.
Я не уверен, почему append()
не ведет себя одинаково, возможно, вы можете подать ошибку!