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


87

베타 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)"

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

설명을위한 스크린 샷


26
무엇 정말 성가신 경고 ...
조니

Swift 3내 자신을 부수고 대신 log단순히 사용하여 실수했습니다 print. 항상 자신 만의 래퍼를 만들어야합니다. 그렇지 않으면 이런 종류의 "새로운 기능"에 얽매일 것입니다.
superarts.org

답변:


106

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

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


제안에서이 변경이 영구적 일지 여부가 명확하지 않습니까? 어떻게 생각해? @Hamish
스테판 드 루카

@ StéphanedeLuca ?? "nil"약간 인기가있는 것처럼 보이는 경고를 침묵시키는 것과 같은 다른 솔루션에 대해 메일 링리스트에 대해 꽤 많은 논의가 있었기 때문에 가까운 장래에 다른 제안에 나타날 수 있습니다. 저는이 해결 방법이 이상적이지 않다는 데 동의합니다. 개인적 Optional(...)으로 강력한 옵션을 위해 문자열에 삽입 될 것으로 예상 하는 것이 분명하다고 생각합니다 .이 경고 IMO가 필요한 것은 IUO의 경우뿐입니다. 그러나 Swift는 지속적으로 진화하고 있으므로 나중에 모두 변경 될 수 있습니다. 그러나 지금은 우리가 가지고있는 것입니다.
Hamish

나는 또한 여기에 더 이상 unboxing하지 않으면 좀 '관련'문제를 발견했습니다. stackoverflow.com/questions/42543512/… 당신이 볼 수 있다면? @Hamish
스테판 드 루카

... 어떤 경우에이 코드 crazyness입니다 :guard result == nil else { print("result was \(result as Optional)") return }
loretoparisi

1
@loretoparisi 왜 사용하지 if let않습니까? 즉 if let result = result { print("result was \(result)"); return }. 모든 조기 반환이 경비원과 함께 할 필요는 없습니다.
Hamish

28

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

옵션 1:

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

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

산출:

5

옵션 2 :

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

var someValue: Int? = 5

if let newValue = someValue {
    print(newValue)
}

산출:

5

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

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


1
저는 처음이지만 인쇄 전에 포장을 확인하는 옵션 2가
마음에 들며

이것을 진지하게 받아들이고 싶다면 force unwrapping은 NO-GO입니다. 내 말은 당신이 앱을 충돌시킬 위험에 처한 것을 콘솔 인쇄하기를 원하기 때문입니까? 그것은 매우 나쁜 제안입니다. 옵션 2는 괜찮습니다. 2ht "Tip"으로는 충분하지 않다고 생각합니다. 답을 바꾸세요!
Martin Mlostek

16

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

13

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"

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

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


이 솔루션은 선택적 체인에서 작동하지 않습니다. 처럼 a?.b?.c.orNil.
Vincent Sit

11

이에 대한 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"

5
자신의 블로그 게시물이 유용하다고 설명에 대한 참조 생각 : oleb.net/blog/2016/12/optionals-string-interpolation
니콜라이 헨릭슨

8

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

스크린 샷 추가

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

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

    예 : :String(describing: employeeName)

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

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

    예 : employeeName ?? “Anonymous” as! String


1
예, Nil-
Coalescing

1
좋은 대답입니다! 당신이 제공하는 다른 문자열 값이 있으면이 잘 작동 무기 호 - 유착
랜스 사마리아

1

스위프트 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>|⭕️

0

명명되지 않은 매개 변수가있는 선택적 제네릭 유형을 허용하는 보간 방법을 만듭니다. 모든 성가신 경고는 마술처럼 사라질 것입니다.

extension DefaultStringInterpolation {
  mutating func appendInterpolation<T>(_ optional: T?) {
    appendInterpolation(String(describing: optional))
  }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.