Type Alias Declaration with Templates in Swift

Is there a decltype equivalent in Swift?

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.

How to create generic protocols in Swift?

It's a little different for protocols. Look at "Associated Types" in Apple's documentation.

This is how you use it in your example

protocol ApiMapperProtocol {
associatedtype T
associatedtype U
func MapFromSource(_:T) -> U
}

class UserMapper: NSObject, ApiMapperProtocol {
typealias T = NSDictionary
typealias U = UserModel

func MapFromSource(_ data:NSDictionary) -> UserModel {
var user = UserModel()
var accountsData:NSArray = data["Accounts"] as NSArray
// For Swift 1.2, you need this line instead
// var accountsData:NSArray = data["Accounts"] as! NSArray
return user
}
}


Related Topics



Leave a reply



Submit