Declaring tuples, or tuple decomposition

The following two statements execute in Swift 5.2.4:

let (x, y) = (14, 17)
print("x = \(x), y = \(y)") // prints: x = 14, y=17

Yet, the following two statements:

let (x: Int, y: Int) = (14, 17)
print("x = \(x), y=\(y)") // fails to execute

cause a compiler error message on the first line:
! Invalid redeclaration of 'Int'
with the "I" of the second Int underlined.

Since the first Int type annotation didn't seem to cause any objections, I deleted the second Int to leave this:

let (x: Int, y) = (14, 17)
print(x, y)

That time I get the error message:

! Use of unresolved identifier 'x'

All of these lines were parsed in a playground on Xcode 11.6.


Answered by OOPer in 637805022
Tested with Xcode 12.0.1/Swift 5.3, and found the similar result except the detailed error message.
Code Block
let (x, y) = (14, 17)
print("x = \(x), y = \(y)") // prints: x = 14, y=17


Code Block
let (x: Int, y: Int) = (14, 17) //->Definition conflicts with previous value
print("x = \(x), y = \(y)") //-> Cannot find 'x' in scope, Cannot find 'y' in scope


Code Block
let (x: Int, y) = (14, 17)
print(x, y) //->Cannot find 'x' in scope


Seems the current Swift compiler does not like tuple-pattern containing type annotations inside.
(It is not clearly expressed in the LANGUAGE REFERENCE of the Swift book.)

Maybe this is because permitting tuple labels.
Code Block
let (labelX: x, labelY: y) = (14, 17)
print("x = \(x), y = \(y)") // prints: x = 14, y=17

(I'm not sure if this pattern has useful use cases.)

You may need to write something like this to give type annotations for tuple decomposition.
Code Block
let (x, y): (Int, Int) = (14, 17)
print("x = \(x), y = \(y)") // prints: x = 14, y=17



Accepted Answer
Tested with Xcode 12.0.1/Swift 5.3, and found the similar result except the detailed error message.
Code Block
let (x, y) = (14, 17)
print("x = \(x), y = \(y)") // prints: x = 14, y=17


Code Block
let (x: Int, y: Int) = (14, 17) //->Definition conflicts with previous value
print("x = \(x), y = \(y)") //-> Cannot find 'x' in scope, Cannot find 'y' in scope


Code Block
let (x: Int, y) = (14, 17)
print(x, y) //->Cannot find 'x' in scope


Seems the current Swift compiler does not like tuple-pattern containing type annotations inside.
(It is not clearly expressed in the LANGUAGE REFERENCE of the Swift book.)

Maybe this is because permitting tuple labels.
Code Block
let (labelX: x, labelY: y) = (14, 17)
print("x = \(x), y = \(y)") // prints: x = 14, y=17

(I'm not sure if this pattern has useful use cases.)

You may need to write something like this to give type annotations for tuple decomposition.
Code Block
let (x, y): (Int, Int) = (14, 17)
print("x = \(x), y = \(y)") // prints: x = 14, y=17



Thank you, OOPer,

I tried your last suggestion of type annotations for tuple decomposition and it worked perfectly in my test playground on Xcode 12.0.1/Swift 5.3.

I'm a Swift newbie trying to learn the language. I read the description of tuples in The Basics chapter of the Swift Language Guide but felt that the explanation omitted any reference to type annotations. I was attempting to experimentally determine how one adds type annotations to a tuple declaration and failed. Your example answered that question and seems to be a more elegant solution on the part of the language developers than the experimental notation that I attempted.

Though I can offer no use cases at this time, ask me that again in a year.

Again, thanks,
Jerry
I just found from the documentation that I can declare, decompose and initialize a tuple constant or variable on the same line:

var z: (x: Int, y: Int) = (14, 17)
print("x = \(z.x), y = \(z.y)")  // prints: x = 14, y=17

This was what I was trying to do from the outset when I got the earlier error. I see now that the error I got was about a conflict in my declaration with x being declared in an earlier declaration.

Declaring tuples, or tuple decomposition
 
 
Q