Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return Nil for Generic Type

I have the following code:

class Function<T> {
    var ptr: () throws -> T

    init<Func>(block: Func, args: AnyObject...) {
        self.ptr = {() throws -> T in
            let result: AnyObject? = nil

            if T.self == Void.self {
                return Void() as! T
            }

            return result //Error Here.. Cannot as! cast it either.. Cannot unsafeBitCast it either..
        }
    }
}

postfix operator ^ { }
postfix func ^ <T>(left: Function<T>) throws -> T {
    return try left.ptr()
}


func call() {
    let block: (String) -> String? = {(arg) -> String? in
        return nil
    }

    let fun = Function<String?>(block: block, args: "Hello")
    fun^
}

The function Block.execute returns AnyObject?. My Generic class Function<T> expects a return type of T.

If T is already String? why can't I return nil?

Is there any way to return nil as type T which is already Optional?

If I make T Optional, then the return type becomes Optional<Optional<String>> which is not what I want.. then the compiler complains that OptionalOptional is not unwrapped with ?? That is how I know that T is already optional.

like image 209
Brandon Avatar asked Jul 22 '26 10:07

Brandon


1 Answers

After a long hunt on google I have finally found an elegant way to do this. It's possible to write a class extension with type constraints.

class Foo<T> {
  func bar() -> T {
    return something
    // Even if T was optional, swift does not allow us to return nil here:
    // 'nil' is incompatible with return type 'T'
  }

}
extension Foo where T: ExpressibleByNilLiteral {
    func bar() -> T {
        return nil
        // returning nil is now allowed
    }
}

The appropriate method will be invoked depending on whether T is optional or not.

like image 79
Julius Naeumann Avatar answered Jul 25 '26 02:07

Julius Naeumann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!