Подтвердить что ты не робот

Массив кортежей в Свифте

У меня есть функция:

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' в вызове

Почему? Помогите пожалуйста....

4b9b3361

Ответ 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() не ведет себя одинаково, возможно, вы можете подать ошибку!