Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast to a Metatype Type in Swift?

Tags:

swift

Can you cast to a Metatype Type in Swift? It really seems like you should be able to (after all you can instantiate objects from Metatypes).

The following doesn't work:

class Super {}

class A : Super {}

let superA:Super = A()
let subType = superA.dynamicType
let afterCast = superA as subType 

//Compiler error: "use of undeclared type 'subType'"

Does anyone know the right way to do this?

Edit:

As newacct pointed out, the result of .dynamicType is obviously not known until runtime, so a compile-time cast to the result of .dynamicType would not make sense.

So the answer is: "You can't" (and there is no good reason to try).

like image 332
thekwiat Avatar asked Jan 10 '15 22:01

thekwiat


People also ask

What is Metatype in Swift?

A metatype type refers to the type of any type, including class types, structure types, enumeration types, and protocol types. The metatype of a class, structure, or enumeration type is the name of that type followed by .

What is a Metatype?

Definition of metatype : a topotype or homeotype determined by the original author of its species.

What is downcast in Swift?

Downcasting. A constant or variable of a certain class type may actually refer to an instance of a subclass behind the scenes.


1 Answers

First of all, as takes a type, not an expression, on the right-hand side. So what you have is a syntax error.

What you seem to be trying to do is "cast" to a type that is computed at runtime. What would that even mean? Let's first consider what is a "cast".

Usually, when we have a cast expression x as T, it has two components:

  • At compile-time: The entire cast expression x as T has compile-time type T?, which allows you to do stuff with the resulting expression that you maybe cannot do on x directly. In other words, it allows you to change the compile-time type.
  • At runtime: It checks whether the runtime type of x is a subtype of T, and if it is, it evaluates to the optional containing that value, otherwise, it evaluates to nil.

If the type T is not known at compile-time, then obviously you cannot do the compile-time part of it. (The compile-time type of the resulting expression cannot, obviously, depend on something which is not known at compile-time.)

The other part, the runtime component, could that be done with a type computed at runtime? Sure. For example,

import Foundation
let afterCast : Super? =
    (superA as AnyObject).isKindOfClass(subType) ? superA : nil

It's not clear if that is what you want.

like image 104
newacct Avatar answered Oct 25 '22 17:10

newacct