Why Specializing a Generic Function Explicitly Is Not Allowed

Why specializing a generic function explicitly is not allowed?

One way to "specialize" the function is by including the generic type as a function parameter:

func serialize<T>(
t: T.Type,
continuation: GenericWithLongName<T, NSError> -> Void ) -> Void { }

Now you can "specialize" the function like this:

serialize(SomeType.self) { 
obj in
...
}

I don't know the answer to why your requested feature is not available. I agree that the feature you recommend would be useful, but in the meantime this works just as well and is almost as concise.

Swift generics - Cannot explicitly specialize a generic function

There is this rule in Swift that you must not explicitly say (using <>s) what the generic parameters of a generic method are. You must give clues to the type inference engine to let it figure the generic parameters out. In this case, you can annotate the type of closure parameter, so that the closure has a type of (Person) -> Void. With this information, the compiler can figure the type of T out.

parser.parse(request: request, onSuccess: { (codable: Person)  in ... }

In other cases, you might have to take in an extra parameter of type T.Type. For example, if your function only takes a type parameter and no value parameters:

func foo<T>() { ... }

In that case, you'd need to add an extra parameter:

func foo<T>(_ type: T.Type) { ... }

so that you can use it as:

foo(Person.self)

Cannot explicitly specialize a generic function when using closures

I believe this is purely a syntax issue. You can't pass the type parameter directly like this. You need to "fill in the type hole" instead. To do that, you need to add the type to navigate:

controller.register(Action.navigate) { [unowned self] (navigate: Navigate?) in ... }

Sometimes that syntax is annoying because it buries the type. You can improve it by rewriting the signature of register this way:

func register<T: Routable>(action: Action, returning: T.type,
withCallback callback: @escaping (T?) -> Void)

You'd then call it this way:

controller.register(action: .navigate, returning: Navigate.self) { 
[unowned self] navigate in
// ...
}

The returning parameter isn't directly used in the function. It just provides a more explicit way to specialize the function.

Swift - Cannot explicitly specialize a generic function

Give the closure an explicit type to fix T:

let task = AsyncTask.background{ (progress: Float -> Void, fulfill: MyAwesomeObject -> Void, reject: NSError -> Void, configure: SwiftTask.TaskConfiguration) -> Void in
let obj = MyAwesomeObject()
//-- ... do work here
fulfill(obj)
}

Explicitly specify generic type constraint when calling function

What way is there to specify the generic type of the function?

The generic type can be inferred from the context:

func bar<T>() -> [T] {
return [T]()
}

let val1 = bar() as [Int] // or:
let val2 : [Int] = bar()

(I cannot answer the other questions.)

Generic parameter 'T' could not be inferred / Cannot explicitly specialize a generic function

Compilation fails because of @autoclosure attribute. When you pass some expression to function that takes @autoclosure the compiler creates a closure with no parameters that returns result of that expression. So, when you pass { var text = "Returning output list\n"; for outline in outlines { text = text + outline.debugDescription + "\n"; }; return text; } then compiler creates a closure returning a closure returning string.

To fix this, you can either add () to the end of expression:

DLog({ () -> String in var text = "Returning output list\n"; for outline in outlines { text = text + outline.debugDescription + "\n"; }; return text; }())

or simplify expression to simple method call, e.g.

DLog(outlines.reduce("Returning output list\n") { $0 + $1.debugDescription + "\n"; })


Related Topics



Leave a reply



Submit