Array of tuples in Swift

前端 未结 3 416
小鲜肉
小鲜肉 2020-11-30 12:32

I have a function:

func parseJSON3(inputData: NSData) -> NSArray {
    var tempDict: (id:Int, ccomments:Int, post_date:String, post_title:String, url:Stri         


        
相关标签:
3条回答
  • 2020-11-30 13:08

    It looks to me like resultArray.append() is treating the tuple a little bit like a variadic parameter, and trying to expand the tuple to match its own arguments. It's complaining about your second parameter because it's only expecting one. I haven't seen this behavior for Array.append() documented anywhere, so I would say it's a bug in Swift.

    Using the appending operator += doesn't seem to have that issue:

    resultArray += tempDict
    
    0 讨论(0)
  • 2020-11-30 13:08

    resultArray.append() seems to be taking tempDict as the first tuple element (id).

    Changing it to :

    resultArray += tempDict

    seems to compile and work.

    I'm not sure why append() doesn't behave the same way, maybe you can file a bug!

    0 讨论(0)
  • 2020-11-30 13:12

    So this is pretty wild - not sure if I would qualify it as a bug or as undocumented behavior, but it's definitely something that should be on the radar for a fix / clarification!

    The situation is that append is treating your argument tempDict (which we would expect to be the only argument to an Array method that takes a single member and adds it to the collection) as the first argument in a signature where it is looking for 5 arguments (!), one for each member of the Tuple type that the Array holds.

    See the following for some interesting behavior (including assigning a label to the single member of a 1-member '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
    

    ...so in your case, where you are seeing the error with append what it wants you to do is (using the labels you used to declare the Tuple as something that looks like argument labels):

    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)
    

    ...and of course, as discussed, you can avoid doing that by just using += instead

    Crazy stuff! could be by design to serve some purpose, could be a consequence of protocol inheritance that wasn't meant to have this effect... would be interesting to know the answer!

    0 讨论(0)
提交回复
热议问题