Search code examples
swiftcircular-reference

Why does this code create a circular reference?


First, thanks for your Help

for _ in 0..<v {
    let edge = readLine()!.split(separator: " ").map { Int(String($0))! }
    let (a: Int, b: Int, w: Int) = (edge[0], edge[1], edge[2]) 
}

It seems to me that it is simply the process of receiving integers and putting them in the tuple, but a Circular reference error is detected. Can you tell me why?

let edge = readLine()!.split(separator: " ").map { Int(String($0))! }
let (a, b, w) = (edge[0], edge[1], edge[2])

It works well if I remove the type annotations.


Solution

  • The error is sort of unclear, but syntax let (a: Int, b: Int, w: Int) is not valid for declaring the types of variables inside the tuple. You are effectively declaring 3 variables named Int with no type. And a and b are just labels you'd be able to refer by continue a or break b, except that would also be problematic, since those labels are inside the tuple.

    You could do one of the following instead:

    Option 1:

    let (a, b, w): (Int, Int, Int) = (edge[0], edge[1], edge[2])
    print(a, b, w)
    

    This is not even a tuple - we defined 3 independent variables - a, b, and w, all of type Int

    Option 2:

    let x: (a: Int, b: Int, w: Int) = (edge[0], edge[1], edge[2])
    print(x.a, x.b, x.w)
    

    In this case we define a single variable x, of type tuple with 3 elements, labeled a, b and w. Notice that we refer to them via x

    Option 2a: We may as well do this: define our type once

    typealias MyType = (a: Int, b: Int, w: Int)
    

    and then use it multiple times:

    for _ in 0..<v {
        let edge = readLine()!.split(separator: " ").map { Int(String($0))! }
        let x: MyType = (edge[0], edge[1], edge[2]) 
    }