2017-01-05 5 views
0

Any? 변수를 보유/보유하지만 요청시이 변수를 지정된 형식으로 변환하는 제네릭 클래스를 선언하고 싶습니다. 나는이 싶습니다이제네릭 형식의 nil 생성 방법

class A<T> { 
    var o: NSObject! 
    var k: String! 
    var v: T { 
     get { return o.value(forKeyPath: k) as! T } 
     set { o.setValue(newValue, forKeyPath: k) } 
    } 
} 

같은 뭔가 o.value(forKeyPath: k)이 경우 nilT에 저장할 수 있도록 작업 할 nil (이 ExpressibleByNilLiteral이다), v 반환 nil (유형 T의). 그것은 그대로, as! 때문에 충돌합니다. 이것을 할 수 있습니까?

이에서 시도한 균열 ( How to make a computed property of a generic class depend on the class constraints에 의해 제안) 다음과 같습니다

class A<T> { 
    var o: NSObject! 
    var k: String! 
    var v: T { 
     get { 
      let x = o.value(forKeyPath: k) 
      if let E = T.self as? ExpressibleByNilLiteral.Type { 
       if let x = x { return x as! T } 
       let n: T = <nil of type T> <---- not sure what to put here 
       return n 
      } else { 
       return x as! T 
      } 
     } 
     set { o.setValue(newValue, forKeyPath: k) } 
    } 
} 

하지만 난 그것을 작동하게하는 방법을 잘 모르겠습니다. 왜

+0

유효한 T (ExpressibleByNilLiteral 준수)가 어떻게 보이는지 보여 줄 수 있습니까? –

+0

문서에서는 "nil은 Swift에서 특별한 의미가 있습니다. 값이 없으면 Optional 타입 만 ExpressibleByNilLiteral을 따르고, 다른 목적으로 nil을 사용하는 타입에 대해서는 ExpressibleByNilLiteral 적합성을 권장하지 않습니다." –

+0

오른쪽 (임의의)'Optional' 타입은'ExpressibleByNilLiteral'을 따릅니다. 'init (nilLiteral :())'만 필요하며'let n : T = E.init (nilLiteral :())을! T '(비록 Optional의 소스 코드에있는 주석은 이것을 막고있는 것으로 보인다). 유감 스럽지만'E.init (nilLiteral :())'이 ...'nil'과'as! '가 실패하기 때문에 충돌이 발생합니다. 이는 호출 할 수있는 일종의'init'을 제공하는 모든 프로토콜에서 작동합니다. 그러나'as! '의 구현은'ExpressibleByNilLiteral'과 "얽혀"있습니다. 문제는 그것을 분리하는 방법입니다. – user3763801

답변

1

확실하지,하지만 실제로 우리가하지 않으려는 경우 어쨌든, 지금 우리는 cast 모든 as! 전화를 대체 할 수 ... 나는 이미이 시도 생각하고 작동하지 않았다

func cast<T>(_ v: Any?)->T { 
    if let E = T.self as? ExpressibleByNilLiteral.Type { 
     if let v = v { 
      return v as! T 
     } else { 
      return E.init(nilLiteral:()) as! T 
     } 
    } else { 
     return v as! T 
    } 
} 

를 작동 nil에 충돌합니다. 우리가 캐스팅 할 유형이 가능하면 예를 들어 내 질문에 게터.

관련 문제