返回Nil为Generic Type

时间:2016-07-06 16:07:23

标签: ios generics swift2

我有以下代码:

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^
}

函数Block.execute返回AnyObject?。我的通用类Function<T>期望返回类型为T

如果T已经String?,为什么我不能返回nil?

有没有办法将nil作为类型T返回,这已经是可选的?

如果我使T可选,则返回类型变为Optional<Optional<String>>这不是我想要的..然后编译器抱怨OptionalOptional没有用??打开这就是我知道T已经是可选的。

4 个答案:

答案 0 :(得分:0)

我用一个讨厌的工作解决了它..我为nil返回类型抛出异常。然后在泛型函数运算符中,我捕获该特定异常并返回nil如果TNilLiteralConvertible ..否则我只是正常执行..

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

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

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

            throw BlockError.BlockReturnsNil
        }
    }
}

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

postfix func ^ <T : NilLiteralConvertible>(left: Function<T>) throws -> T {
    do {
        return try left.ptr() 
    }
    catch BlockError.BlockReturnsNil {
        return nil
    }
}

答案 1 :(得分:0)

仅当Any?是可选的且Tnil时,以下广告Tfrom才会返回nil。如果from无法转换为T,则会崩溃。

func cast<T>(from v: Any?)->T {        
    return v as! T
}

func cast<T>(from v: Any?)->T where T: ExpressibleByNilLiteral {
    guard let v = v else { return nil }
    return v as! T
}

答案 2 :(得分:0)

这就是Swift 3.1的技巧。修改user3763801的答案。

func cast<T>(_ v: Any) -> T {
    return v as! T
}

答案 3 :(得分:0)

在Google长期搜寻之后,我终于找到了一种优雅的方法。可以编写具有类型约束的类扩展。

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
    }
}

根据T是否可选,将调用适当的方法。