diegoperini
diegoperini

Reputation: 1806

Is there a decltype equivalent in Swift?

In C++11 and latter, it is possible to use a compile time function like syntax named decltype() to reuse declaration type of a variable to declare another one without rewriting the type signature. Is there any equivalent syntactic tool in Swift?

C++ Example:

class SomeClass {
public: 
    SomeVeryLongTypeName* my_prop;
}

void foo() {
    SomeClass my_var = SomeClass();

    // Below code is a variable declaration, not a function call
    declytype(my_var.my_prop) some_prop = nullptr;

    // Below is same as above
    SomeVeryLongTypeName* some_prop = nullptr;
}

Upvotes: 4

Views: 441

Answers (1)

dfrib
dfrib

Reputation: 73186

There is, as far as I know, no direct equivalent syntactic tool readily available in Swift.

For something slightly similar you could, however, make use of generics to gain access to (at compile time) a metatype (grammar: metatype-type → type­.­Type), whereafter you can use an initializer expression to construct an instance of the concrete type (of the metatype).

protocol Initializable {
    init()
}

typealias SomeVeryLongTypeName = Int
extension SomeVeryLongTypeName : Initializable {}

class SomeClass {
    let my_prop : SomeVeryLongTypeName
    required init() { my_prop = 1 }
}

func declmetatype<T: Initializable>(_: T) -> T.Type {
    return T.self
}

func foo() {
    let my_var = SomeClass()
    let some_prop = declmetatype(my_var.my_prop).init()
    some_prop = my_var.my_prop + 1
}

In foo() above, some_prop is of type SomeVeryLongTypeName (which, here, is simply Int), which due to Swift's static typing is naturally known at compile time.

Note, however, that in Swift we cannot use this technique to only declare types, but must also instantiate them. Moreover, there's no concept of "default initializers" in Swift (as compared to default CTOR:s in C++), hence the need to constrain the generic typeholder in declmetatype(...) to a protocol of our own, where we provide a blueprint to some initializer we'd like to use in a "default sense" from the metatype.

We may visit the Language Reference - Types - Metatypes for additional details on metatypes, particularly:

Use an initializer expression to construct an instance of a type from that type’s metatype value. For class instances, the initializer that’s called must be marked with the required keyword or the entire class marked with the final keyword.

Where I've emphasized the available use of metatypes to construct instances of types (as shown above), which does not, however, cover using metatypes to only declare types.

Upvotes: 1

Related Questions