Nathan Barrett
Nathan Barrett

Reputation: 59

Swift casting one custom type to another

I have a function that returns "Any?" but in my particular instance, I know that it should return a custom "Tuple2" object. But since the Tuple2 is part of a separate Swift plugin, I cannot access the struct directly. I have a duplicate of that struct in my main swift code and I'm trying to cast the "Any?" result to my duplicate struct. But I cannot convince the compiler that such a cast is allowed.

Any ideas on how to get around this?

An example that outlines the problem in a single file is as follows.


typealias Scalar = Double

//~~~~~~ THIS HAPPENS IN THE PLUGIN ~~~~~~
struct Tuple2 {
    public var x0: Scalar
    public var x1: Scalar
    
    public init(_ x0:Scalar, _ x1:Scalar) {
        self.x0 = x0
        self.x1 = x1
    }
}

let A = Tuple2(1.0,2.0)

let B = A as! Any?

//~~~~~~ THIS HAPPENS IN MY CODE ~~~~~~
struct TupleTwo {
    public var x0: Scalar
    public var x1: Scalar
    
    public init(_ x0:Scalar, _ x1:Scalar) {
        self.x0 = x0
        self.x1 = x1
    }
}

let C = B as! TupleTwo //Error thrown here

print("x0:\(C.x0) x1:\(C.x1)")

Upvotes: 1

Views: 316

Answers (1)

Alexander
Alexander

Reputation: 63271

But I cannot convince the compiler that such a cast is allowed.

Good! Because it’s not.

Swift (mostly) uses nominal typing, not structural typing. That is, two types are equal only if their (fully qualified) names are equal. Two nominal types with different names, even having the exact same content, are never equivalent.

Your copy of TupleTwo in this module introduces a new type that is completely unrelated to the TupleTwo of the other module you’re using.

To solve your problem you’ll need to import the other module, and use its TupleTwo type in your cast.

Upvotes: 2

Related Questions