2016-07-06 2 views
3

에 나는 다음과 같은 코드가 있습니다반환 무기 호 일반 유형

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을 반환 할 수 없습니까?

이미 선택 사항 인 T 유형으로 nil을 반환하는 방법이 있습니까? 내가 T 옵션, 다음 반환 형식 내가 .. 원하는하지 않은 Optional<Optional<String>>을하게 한 경우

는 컴파일러 OptionalOptional가 나는 T 이미 선택 것을 알고 어떻게 그 ??로 풀어되지 않는다는 불평.

+0

이'execute' 메소드는 어디에서 오는가? – LopSae

+0

내부 라이브러리에서. 항상 'AnyObject?'를 반환합니다. – Brandon

+0

놀이터에 복사 붙여 넣기처럼 쉽게 재현 할 수있는 예제를 만들어보십시오. – LopSae

답변

0

나는 주위의 불쾌한 일을 해결했다. 나는 nil return 타입에 대한 예외를 던진다. 그런 다음 일반적인 기능 연산자에 나는 다음은 T는 선택 사항이며 from 인 경우에만 Any?T에이 nil를 반환 캐스트 ..

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

TNilLiteralConvertible입니다 nil 경우 특정 예외가 .. 반환 그렇지 않으면 난 그냥 정상적으로 실행할 것을 잡아 nil. fromT으로 전송할 수없는 경우 오류가 발생합니다.

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

이것은 스위프트 3.1의 트릭입니다. user3763801의 답변 수정.

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