Decomposing tuple contents into a mixed var and let declaration?

It feels like I might be missing something obvious here, but:

We can do this (the exact function doesn't matter, the point is that it returns a tuple):

let (a, b) = x.quotientAndRemainder(dividingBy: y)

and this:

var (a, b) = x.quotientAndRemainder(dividingBy: y)

but not this:

(var a, let b) = x.quotientAndRemainder(dividingBy: y) // ERROR: 'let' cannot appear nested inside another 'var' or 'let' pattern

which is what I want, ie in the rest of this scope, I want a to be mutable and b to be a let constant.

Is there any simpler way of achieving this than the following?


Workaround A:

let (_a, b) = x.quotientAndRemainder(dividingBy: y)
var a = _a

Workaround B:

guard case (var a, let b) = x.quotientAndRemainder(dividingBy: y), true
  else { fatalError() }

Workaround C:

var a: Int
let b: Int
(a, b) = x.quotientAndRemainder(dividingBy: y)

If not, would it be reasonable to allow (var a, let b) = … ?

5 Likes

If you don't mind annotating the type (which sometimes can be unyieldy). You can also do:

let a: ...
var b: ...
(a, b) = ...
3 Likes

Ah! I'll add that as Workaround C if you don't mind :slight_smile:.

1 Like