[swift] 해결 방법“문자열 보간은 선택적 값에 대한 디버그 설명을 생성합니다. 이것을 명시 적으로 만들려고 했습니까?” Xcode 8.3 베타에서?

베타 8.3부터 zillions는 “문자열 보간이 선택적 값에 대한 디버그 설명을 생성합니다.이를 명시 적으로 만들려고 했습니까?”라고 경고합니다. 내 코드에 나타났습니다.

예를 들어, 다음과 같은 상황에서 경고가 표시되어 옵션이 nil로 이어질 수 있습니다.

let msg = "*** Error \(options["taskDescription"]): cannot load \(sUrl) \(error)"

이전에 설계했듯이 옵션은 ‘nil’로 보간되는 것이 좋습니다. 그러나 컴파일러는 마음을 바꿨습니다.

컴파일러가 제안하는 것은 다음과 같은 설명과 함께 String 생성자를 추가하는 것입니다.

let msg = "*** Error \(String(describing: options["taskDescription"])): cannot load \(sUrl) \(error)"

분명히 결과는 명백하지만 제 생각에는 매우 번거 롭습니다. 더 나은 옵션이 있습니까? 모든 경고를 수정해야합니까? 아니면 다음 베타를 기다려야합니까?

설명을위한 스크린 샷



답변

이는 결과 문자열로 보간 하는 것이 종종 바람직하지 않으며 암시 적으로 언 래핑 된 선택 사항이있는 경우 특히 놀랍기 때문에이 풀 요청 에서 변경된 사항 입니다. 이 변경 사항에 대한 자세한 내용은 여기 메일 링리스트 에서 볼 수 있습니다 .Optional(...)

풀 리퀘스트 토론에서 언급했듯이 (불행히도 Xcode는 아니지만)-경고를 사용하는 것보다 약간 더 좋은 방법 String(describing:)은 보간하는 옵션 유형에 캐스트를 추가하는 것입니다. 예를 들면 다음과 같습니다.

var i: Int? = 5
var d: Double? = nil

print("description of i: \(i as Int?)")    // description of i: Optional(5)
print("description of d: \(d as Double?)") // description of d: nil

다음과 같이 일반화 할 수도 있습니다 as Optional.

print("description of i: \(i as Optional)") // description of i: Optional(5)
print("description of d: \(d as Optional)") // description of d: nil

Swift 5에서 SE-0228에 의해 도입 된 새로운 문자열 보간 시스템과 함께 또 다른 옵션은 다음에 대한 사용자 정의 appendInterpolation오버로드 를 추가하는 것입니다 DefaultStringInterpolation.

extension DefaultStringInterpolation {
  mutating func appendInterpolation<T>(optional: T?) {
    appendInterpolation(String(describing: optional))
  }
}

var i: Int? = 5
var d: Double? = nil

print("description of i: \(optional: i)") // description of i: Optional(5)
print("description of d: \(optional: d)") // description of d: nil

원하는 경우 인수 레이블을 제거하여 모듈 내에서 (또는으로 표시 한 경우 특정 파일 내에서) 경고를 완전히 비활성화 할 수도 있습니다 fileprivate.

extension DefaultStringInterpolation {
  mutating func appendInterpolation<T>(_ optional: T?) {
    appendInterpolation(String(describing: optional))
  }
}

var i: Int? = 5
var d: Double? = nil

print("description of i: \(i)") // description of i: Optional(5)
print("description of d: \(d)") // description of d: nil

개인적으로는 인수 레이블을 유지하고 싶습니다.


답변

이 문제를 처리하는 두 가지 쉬운 방법.

옵션 1:

첫 번째는 강타 (!)를 사용하여 반환하려는 값을 “강제 풀기” 하는 것입니다 .

var someValue: Int? = 5
print(someValue!)

산출:

5

옵션 2 :

더 나은 방법이 될 수있는 다른 방법은 반환하려는 값 을 “안전하게 래핑 해제” 하는 것입니다.

var someValue: Int? = 5

if let newValue = someValue {
    print(newValue)
}

산출:

5

옵션 2로 이동하는 것이 좋습니다.

팁 : 항상 풀릴 값이 있는지 확실하지 않으므로 가능한 경우 강제 풀기 (!)를 피하십시오.


답변

String (describing : optional)을 사용하는 것이 가장 간단합니다.

기본값 ?? 문자열이 아닌 경우에는 의미가 없습니다 (예 : Int).
Int가 nil이면 로그에 ‘nil’이 기본값이 아닌 다른 Int (예 : 0)로 표시되기를 원합니다.

테스트 할 플레이 그라운드 코드 :

var optionalString : String? = nil
var optionalInt : Int? = nil

var description_ = ""
description_ = description_ + "optionalString: \(String(describing: optionalString))\r"
description_ = description_ + "   optionalInt: \(String(describing: optionalInt))\r"

print(description_)

산출

optionalString: nil
optionalInt: nil


답변

Xcode 8.3으로 업데이트하고 많은 경고 메시지를받은 후, 추가하기 쉬운 원래 출력 동작과 비슷하며 코드와 출력 모두에서 “String (describing :)”사용의 장황함을 줄인 다음을 생각해 냈습니다. .

기본적으로 옵션에있는 것을 설명하는 문자열을 제공하는 선택적 확장을 추가하거나 설정되지 않은 경우 단순히 “nil”을 추가하십시오. 또한 선택 사항의 항목이 문자열이면 따옴표로 묶습니다.

extension Optional {
    var orNil : String {
        if self == nil {
            return "nil"
        }
        if "\(Wrapped.self)" == "String" {
            return "\"\(self!)\""
        }
        return "\(self!)"
    }
}

그리고 놀이터에서의 사용법 :

var s : String?
var i : Int?
var d : Double?

var mixed = "s = \(s.orNil)    i = \(i.orNil)   d = \(d.orNil)" // "s = nil    i = nil   d = nil"

d = 3
i = 5
s = ""
mixed = "s = \(s.orNil)    i = \(i.orNil)   d = \(d.orNil)" // "s = ""    i = 5   d = 3.0"

s = "Test"
d = nil
mixed = "s = \(s.orNil)    i = \(i.orNil)   d = \(d.orNil)" // "s = "Test"    i = 5   d = nil"

다음 링크에서 도움을 주셔서 감사합니다.

변수가 선택 사항인지 여부 및 랩핑 유형 확인


답변

이에 대한 Ole Begeman의 수정 사항을 참조하십시오 . 나는 그것을 좋아한다. ???다음과 같이 사용할 수 있는 연산자를 만듭니다 .

var someValue: Int? = 5
print("The value is \(someValue ??? "unknown")")
// → "The value is 5"
someValue = nil
print("The value is \(someValue ??? "unknown")")
// → "The value is unknown"


답변

이 경고가 포함 된 줄에 표시된 노란색 삼각형을 두 번 클릭합니다. 두 가지 솔루션 이있는 FixIt 이 표시됩니다 .

스크린 샷 추가

  1. String(describing:)이 경고를 끄려면 사용하십시오 .

    이것을 사용하면 String(describing:<Variable>)

    예 : :String(describing: employeeName)

  2. default value이 경고를 피하기 위해를 제공하십시오 .

    이것을 사용하면 (<Variable> ?? default value)

    예 : employeeName ?? “Anonymous” as! String


답변

스위프트 5

내 솔루션은 extension어떤 Optional개체를 Any.

개체를 기록하거나 인쇄 할 때 실제 object또는 <nil>⭕️(텍스트와 시각적 문자의 조합)을 볼 수 있습니다 . 특히 콘솔 로그를 보면 유용합니다.

extension Optional {
    var logable: Any {
        switch self {
        case .none:
            return "<nil>|⭕️"
        case let .some(value):
            return value
        }
    }
}

// sample
var x: Int?
print("Logging optional without warning: \(x.logable)")
// → Logging optional without warning: <nil>|⭕️