zneak
zneak

Reputation: 138051

How can I call the most precise overload from a generic function?

This guy says that Swift generic methods can be overloaded as a way to specialize them:

func testMethod<T: Comparable>(v: T) -> T {
    return v
}
func testMethod(v: Int) -> Int {
    return v * 12345
}

So I'm trying to get something somewhat similar. I have made a class to read integers from byte buffers. It notably defines these methods:

public func read(type: Int32.Type) -> Int32 {
    return /* implementation detail */
}

public func read<T: IntegerType>(type: T.Type) -> T {
    let bug: T! = nil
    return bug
}

public func readInto<T: IntegerType>(inout into: T) {
    into = read(T.self)
}

There are many more read(type: [U]Int[bits]) methods to overload the read<T> method. The generic method is meant as a catch-all to crash my program if I try to read from a type that wasn't covered by the non-generic implementations.

The readInto method is a convenience method so that I don't have to repeat the object's type. If I want to read into an Int32 variable, instead of doing variable = reader.read(type: Int32.self), I can do reader.read(&variable), and since I hate to repeat myself, I feel that this is better.

My problem is that the call from readInto systematically goes to the catch-all read<T>, even when a more precise overload exists.

Is there any way to get it to call the most precise overload from a generic method?

Upvotes: 1

Views: 112

Answers (1)

zneak
zneak

Reputation: 138051

This does not solve the general problem, but Swift functions can be overloaded from their return types. For instance:

func foo() -> Int16 {
    return 0
}

func foo() -> Int32 {
    return 1
}

let i16: Int16 = foo() // 0
let i32: Int32 = foo() // 1
let i = foo() // compile-time error: ambiguous

This effectively means that I don't need a readInto method to read into a variable of a given type, I can just assign to it the result of a read() call and be done with it, damned be generics.

Upvotes: 1

Related Questions