Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding syntax for an array of tuples in Swift

I'm trying to understand syntax for arrays of tuples in Swift:

If I create a tuple:

var gameScore: (points: Int, player: String)

I can assign values like this:

gameScore = (1700, "Lisa")

And create an array of this tuple:

var gameScores = [gameScore]

I can append to the array this way:

gameScores.append((1650, "Bart"))

And this way:

gameScore = (1600, "Maggie")
gameScores += [gameScore]

But not this way:

gameScores += [(1600, "Maggie")]

Playground error is:

Playground execution failed: error: Tuples Playground.playground:38:1: error: cannot convert value of type '[(points: Int, player: String)]' to expected argument type 'inout _' gameScores += [(1600, "Maggie")]

However, this way works:

gameScores += [(points: 1600, player: "Maggie")]

Yes – I have code above that will work, but I'm trying to figure out what I'm not understanding in the failing syntax. Elements don't need to be named for the .append() method, but they need to be named for += [()].

like image 593
Gallaugher Avatar asked Oct 19 '22 00:10

Gallaugher


1 Answers

The Swift type inference system is being stretched to the point of breaking here. Swift is having trouble inferring the type of [(1600, "Maggie")] in your example. If you give it a little more information, your example will compile:

gameScores += [(1600, "Maggie") as (points: Int, player: String)]

gameScores += [(1600, "Maggie")] as [(points: Int, player: String)]

and

gameScores = gameScores + [(1600, "Maggie")]

all compile.

It seems Swift is having trouble inferring the type when += is involved.

Looking at the definition of +=:

func +=<C : Collection>(lhs: inout Array<C.Iterator.Element>, rhs: C)

shows that the types of the lhs and rhs are different. Swift is having trouble reconciling the types of the lhs and the rhs from the information given. It seems to be starting with the rhs and then concludes that the type of the lefthand side is inout _ and it tries to reconcile that with the type of gameScores which is [(points: Int, player: String)]. Should it be able to infer the types? Perhaps, but in this case, since you have an easy workaround, I say give the compiler a break and give it the explicit type information and make its job easier:

gameScores += [(points: 1600, player: "Maggie")]
like image 77
vacawama Avatar answered Nov 04 '22 21:11

vacawama