2017-10-24 19 views
0

다음 코드 조각이 있습니다. MyDisplayable에는 3 개의 옵션 String이 있으며, 확장을 통한 프로토콜의 기본 구현이 있습니다. 내 질문은, 확장에서 3 개의 문자열을 반환한다고 확신하기 때문에 비 선택적으로 사용할 수있는 방법이 있습니까? 다른 구현으로 덮어 쓰면 위험 할 수 있습니다. (아래 코드의 질문 1과 2 참조)선택적 읽기 전용 변수에 대한 스위프트 프로토콜 기본 구현

고마워요!

protocol MyDisplayable { 
    var displayName: String? { get } 
    var shortDescription: String? { get } 
    var longDescription: String? { get } 
} 

protocol MyObject : MyDisplayable, CustomStringConvertible { 
} 

extension MyObject { 
    var displayName: String? { 
     return "noname" 
    } 

    var shortDescription: String? { 
     return "something can't be described" 
    } 

    var longDescription: String? { 
     return "no way to describe it further" 
    } 

    var description: String { 
     // **1. is there a way to use the strings as if they are non-optional?** 
     // **2. is it a problem if another class implements the protocol and returns `nil` for any of the strings, but here they are force unwrapped?** 
     return "\(displayName!): \(shortDescription!)\n\(longDescription!)" 
    } 
} 

class Something : MyObject { 
} 

let something = Something() 
print("Something: \(something)") 
+0

만약 내가 당신이라면 나는 그런 것들을 복잡하게 만들지 않을 것입니다; 이 특정 문제를 해결하는 대신 목표 달성을위한 다른 방법을 찾아야합니다. 강타 주위에서 길을 해킹하면 가끔 컴파일러에서 무거워지는 것 외에도 상황이 악화됩니다. 아마 당신은 *'MyObject'없이 * 할 수 있고, 단지'MyDisplayable'에 옵션이 아닌 문자열을 기본 값으로 제공 할 수 있습니다. – user1244109

답변

0

불행히도 선언 된 옵션을 비표준으로 처리 할 수 ​​없습니다. 프로토콜에서이 문자열을 선택 사항으로 선언 했으므로 해당 프로토콜을 구현할 때 선택적으로 유지됩니다.

그러나 getter-setter를 사용하여 변수가 선택 사항으로 선언 된 경우에도 변수가 항상 일부 값을 저장하는지 확인할 수 있습니다.

나는 몇 가지 코드와 함께 자세히 설명합니다 :

protocol MyDisplayable { 
    var displayName: String? { get set } 
    var shortDescription: String? { get set } 
    var longDescription: String? { get set } 
} 

protocol MyObject : MyDisplayable, CustomStringConvertible { 
} 

extension MyObject { 
    var displayName: String? { 
     get { 
      return "noname" 
     } 
     set { 
      newValue ?? "" 
     } 
    } 

    var shortDescription: String? { 
     get { 
      return "something can't be described" 
     } 
     set { 
      newValue ?? "" 
     } 
    } 

    var longDescription: String? { 
     get { 
      return "no way to describe it further" 
     } 
     set { 
      newValue ?? "" 
     } 
    } 

    var description: String { 
     // **1. is there a way to use the strings as if they are non-optional?** 
     // **2. is it a problem if another class implements the protocol and returns `nil` for any of the strings, but here they are force unwrapped?** 
     return "\(displayName!): \(shortDescription!)\n\(longDescription!)" 
    } 
} 

class Something : MyObject { 
} 

let something = Something() 
print("Something: \(something)") 

지금 다른 클래스는 그 문자열에 nil이 값들은 "빈 문자열을 반환합니다"를 덮어 쓰는 경우에도 마찬가지입니다. 그들은 선택 사항으로 선언되었으므로 여전히 선택 사항이지만, 이제는 항상 nil이 아닌 값을 갖습니다.

+0

좋은 생각을 깰 { 전무 반환} } . – hzxu

0

기본 구현에서 조건부 래핑 해제는 어떻습니까?

return "\(displayName ?? ""): \(shortDescription ?? "")\n\(longDescription ?? "")" 
+0

그래,이 방법이 더 좋지만 다른 클래스가 기본 구현을 덮어 쓰면 문자열이 설명을 나눌 수있는'nil '이 될 수 있다는 문제점이있다. – hzxu

+0

클래스에서 displayName을 재정 의하여 nil을 반환한다고 가정 해 보겠습니다. 여전히 작동합니다. 클래스 무언가 : MyObject { var displayName : String? 이 프로토콜은 setter를 노출하는 것을 수치가 비록 습관, 위의 구현을 –