2014-09-02 1 views
6

나는 아주 간단한 작업이라고 생각하는 것을하고 있습니다. 키가 존재하면 사전에서 가치를 얻으려고합니다. 나는이 사전을 몇 가지 키에 대한 일을하고 다음 (모두 기본적으로 JSON 개체를 디코딩) 존재하는 경우 개체를 만드는 중입니다. 나는 언어에 새로운 오전하지만이 작동해야처럼 날 것으로 보인다, 아직하지 않는 : 나는이 작업을 수행 할 경우, 작동하지만 Operand of postfix ? should have optional type; type is (String, AnyObject)신속 선택 사항 : 언어 문제 또는 잘못된 것을하고 있습니까?

: 그것은 나에게 오류를 제공

class func fromDict(d: [String : AnyObject]!) -> Todo? { 
    let title = d["title"]? as? String 
    // etc... 
} 

class func fromDict(d: [String : AnyObject]!) -> Todo? { 
    let maybeTitle = d["title"]? 
    let title = maybeTitle as? String 
    // etc... 
} 

기본 대체로 보이지만 일부 언어의 뉘앙스가 누락 될 수 있습니다. 아무도 이것에 관해 밝힐 수 있습니까?

+0

'd [ "title"]'은 선택 사항입니다. 잘못 입력 한 후에'?'를 사용합니다. 이 연산자의 유스 케이스는'object? .property'가 될 것이므로'object.property'는'object'가 ** not **'nil' 일 때만 평가할 것입니다. 그렇지 않으면'nil'을 리턴합니다 – Binarian

답변

3

권장 패턴은 그것은 아마도 정말 뉘앙스의 질문

if let maybeTitle = d["title"] as? String { 
    // do something with maybeTitle 
} 
else { 
    // abort object creation 
} 

입니다. 양식 array[subscript]?은 모호합니다. 이는 결과 (String)를 의미하는 동안 전체 사전 (<String:AnyObject>)이 선택 사항임을 의미하기 때문에 모호합니다. 위의 패턴에서 Dictionary은 선택적 유형의 일부 핵심 결과에 액세스한다고 가정하도록 설계되었습니다.

var dictionary = ["one":"1", "two":"2"] 
// or var dictionary = ["one":1, "two":2] 
var message = "" 
if let three = dictionary["three"] as Any? { 
    message = "\(three)" 
} 
else { 
    message = "No three available." 
} 
message // "No three available." 

이 스위프트 문자열, 숫자 등을 포함한 모든 비 객체 스위프트 객체로 작동합니다 :

실험 후

as? 여기에, 그냥, 모호한 이상인 것이 몰래 내 솔루션입니다 . String는 스위프트의 개체가 아님을 상기시켜 주신 Viktor에게 감사드립니다. +

당신은 당신이 일이 여기에가는 몇 가지가 있습니다 String?

+0

나는 너무 생각했습니다. ** **하지만 **은 @vacawama와 같이 놀이터에서 오류를 던집니다. 딕셔너리에서 값으로 'NSString'은'(String, AnyType)'형식으로 표시되며 같은 줄에'String?'으로 캐스팅 될 수 없습니다. ... 그리고 어쩌면 * 아마도 * 더 이상 어울리지 않을 것입니다. 그렇지 않으면 if bracket으로 들어가기 전에 바로 설정되지 않을 것입니다. – Binarian

+0

사전이 OP의 사전처럼'[String : AnyObject]! '유형 인 경우? 이것은 나를 위해 놀이터에서 작동하지 않습니다. – vacawama

+0

'사전이'[String : AnyObject]! '인 경우 let three = dictionary [ "three"] NSObject?'가 작동합니다. – vacawama

2

처럼 적절한 옵션 유형 Any?을 대체 할 수있는 값의 종류를 알고 있다면.

1) ? (d["title"]?)은 올바르지 않습니다. d["title"]을 푸는 경우 !을 사용하고 title이 사전의 유효한 키가 아닌 경우 충돌이 발생하므로주의해야합니다. (?선택적 체인에 사용됩니다 (옵션 변수에서 메소드를 호출하거나 속성에 액세스하려는 경우처럼).이 경우 액세스는 옵션이 nil 인 경우 아무 작업도 수행하지 않습니다. d["title"]을 푸는 중이므로 ?을 그대로 두십시오. 사전 액세스는 키가 존재하지 않을 수 있으므로 항상 선택적 값을 리턴합니다.

let maybeTitle = d["title"] as? String 

오류 메시지가 변경 : 오류 : '(문자열, AnyObject가)' '문자열'

문제로 변환되지 않습니다 당신이 그 문제를 해결한다면

2) 여기에 String은 개체가 아닙니다. NSString으로 전송해야합니다.

let maybeTitle = d["title"] as? NSString 

maybeTitleNSString? 인 발생합니다. d["title"]이 없거나 유형이 NSString 대신 실제로 NSNumber 인 경우 선택 사항의 값은 nil이지만 앱이 중단되지 않습니다.

3) 문 :

let title = maybeTitle as? String 

당신이 원하는만큼 선택적인 변수 랩을 해제하지 않습니다. 올바른 형식은 다음과 같습니다
if let title = maybeTitle as? String { 
    // title is unwrapped and now has type String 
} 

그래서 모두 함께 그 퍼팅 :

if let title = d["title"] as? NSString { 
    // If we get here we know "title" is a valid key in the dictionary, and 
    // we got the type right. title has now been unwrapped and is ready to use 
} 

title이 개체를 보유하고 있기 때문에 사전에 저장되는 것입니다 유형 NSString이있을 것이다. 당신은 당신이 String로 할 수있는 NSString 대부분 모든 것을 할 수 있지만 title 필요하면 당신이 할 수있는 String 수 :

if var age:Int = d["age"] as? NSNumber { 
    age += 1 
} 
:

if var title:String = d["title"] as? NSString { 
    title += " by Poe" 
} 

과 당신의 사전 NSNumber의도가있는 경우

+0

NSString과 String 사이에는 자동 변환이 있기 때문에; 당신은 캐스팅하지 않고 NSString을 String으로 저장하고있다. String을 원한다면 NSString을 사용하는 것은 혼란 스럽다. – Binarian

+1

NSString을 사용해야하는 것은 수치 스럽지만 코코아 터치와 코코아 터치에서 나온 사전을 다룰 때는 사실입니다. 사전이'[String : Any]'라면 생명은 훨씬 쉬울 것입니다. – vacawama

+0

모든 NSObject와 마찬가지로 NSString은 이미 선택 사항이므로 'as'대신 'as?'를 사용할 필요가 없습니다. – Binarian