कैसे हल करने के लिए "स्ट्रिंग प्रक्षेप एक वैकल्पिक मूल्य के लिए डिबग विवरण तैयार करता है; क्या आपको यह स्पष्ट करने का मतलब है? " Xcode में 8.3 बीटा?


87

8.3 के बाद से, zillions चेतावनियाँ "स्ट्रिंग प्रक्षेप एक वैकल्पिक मूल्य के लिए एक डिबग विवरण पैदा करता है? क्या आप इसे स्पष्ट करने का मतलब है?" मेरे कोड में दिखाई दिया।

उदाहरण के लिए, चेतावनी निम्न स्थिति में पॉप अप हुई, जहां विकल्प शून्य हो सकते हैं:

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

जैसा कि पहले डिज़ाइन किया गया था, मेरे लिए (और कंपाइलर) वैकल्पिक 'एनआईएल' के रूप में प्रक्षेपित होना ठीक था। लेकिन कंपाइलर ने अपना विचार बदल दिया।

कंपाइलर ने सुझाव दिया है कि स्ट्रिंग कंस्ट्रक्टर को विवरण के साथ जोड़ना है:

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

जाहिर है, परिणाम स्पष्ट हैं लेकिन मेरी राय में बहुत ही बोझिल हैं। क्या कोई बेहतर विकल्प है? क्या मुझे उन सभी चेतावनी को ठीक करना होगा या अगले बीटा के लिए बेहतर प्रतीक्षा करनी होगी?

विवरण के लिए स्क्रीनशॉट


26
वास्तव में कष्टप्रद चेतावनी ...
जॉनी

Swift 3मेरी खुद को तोड़ दिया logऔर मैंने printइसके बजाय बस का उपयोग करके एक गलती की । हमेशा अपना खुद का रैपर बनाना चाहिए अन्यथा आप "नई सुविधा" के इस प्रकार से खराब हो जाएंगे।
superarts.org

जवाबों:


105

यह एक बदलाव है जो इस पुल अनुरोध में इस तथ्य के कारण किया गया था कि Optional(...)परिणामी स्ट्रिंग में प्रक्षेप अक्सर अवांछनीय होता है, और विशेष रूप से अंतर्निहित अलिखित वैकल्पिक के साथ मामलों में आश्चर्यजनक हो सकता है । इस बदलाव की पूरी चर्चा आप यहां मेलिंग सूची पर देख सकते हैं ।

जैसा कि पुल अनुरोध चर्चा में उल्लेख किया गया है (हालांकि दुर्भाग्य से एक्सकोड द्वारा नहीं) - एक थोड़ा अच्छा तरीका यह है कि इसके उपयोग की तुलना में चेतावनी को चुप 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

स्विफ्ट 5 में, नए स्ट्रिंग प्रक्षेप प्रणाली द्वारा शुरू की के साथ एसई 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

हालांकि व्यक्तिगत रूप से मैं तर्क लेबल रखना पसंद करूंगा।


प्रस्ताव से, यह स्पष्ट नहीं है कि क्या यह परिवर्तन स्थायी होने जा रहा है? तुम क्या सोचते हो? @ हमीश
स्टीफन डे लुका

@ StéphanedeLuca मेलिंग सूची पर अन्य समाधानों के बारे में काफी चर्चा हुई, जैसे ?? "nil"कि चेतावनी को चुप करने की अनुमति , जो कि हल्के से लोकप्रिय लग रहा था, इसलिए निकट भविष्य में एक अन्य प्रस्ताव में दिखाई दे सकता है। मैं इस बात से सहमत हूं कि यह समाधान आदर्श से कम है - व्यक्तिगत रूप से, मुझे लगता है कि Optional(...)मजबूत वैकल्पिक के लिए स्ट्रिंग में प्रक्षेपित होने की अपेक्षा स्पष्ट है - यह वास्तव में IUOs का मामला था जिसे इस चेतावनी IMO की आवश्यकता थी। लेकिन स्विफ्ट लगातार विकसित हो रही है, इसलिए यह सब बाद में नीचे लाइन में बदल सकता है। लेकिन अभी के लिए, यह वही है जो हमें मिला है।
हमीश

मैं भी कुछ हद तक 'संबंधित' मुद्दे पर ठोकर खाई है, अगर यहाँ अब और नहीं unboxing stackoverflow.com/questions/42543512/… अगर आप एक नज़र हो सकता है? @ हमीश
स्टीफन डे लुका

... किसी भी स्थिति में यह कोड पागलपन है:guard result == nil else { print("result was \(result as Optional)") return }
लोरेटोपरिसि

1
@loretoparisi का उपयोग क्यों नहीं किया जाता है if let? यानी if let result = result { print("result was \(result)"); return }। सभी शुरुआती रिटर्न गार्ड के साथ करने की आवश्यकता नहीं है।
हमीश

29

इस मुद्दे से निपटने के दो आसान तरीके।

विकल्प 1:

पहला "बल-अलिखित" द्वारा होगा जो आप एक बैंग (!) का उपयोग करके वापस करना चाहेंगे

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

आउटपुट:

5

विकल्प 2:

दूसरा तरीका, जो बेहतर तरीका हो सकता है - वह है "सुरक्षित रूप से अनचाहे" जिस मूल्य को आप वापस करना चाहते हैं।

var someValue: Int? = 5

if let newValue = someValue {
    print(newValue)
}

आउटपुट:

5

विकल्प 2 के साथ जाने की सलाह देंगे।

युक्ति: जहाँ हम संभव नहीं हैं यदि हम हमेशा अपरिवर्तित रहने का मूल्य नहीं रखेंगे, तो बल प्रयोग से बचें!


1
मैं नया हूं, लेकिन मुझे प्रिंट से पहले रैपिंग को मान्य करने के लिए विकल्प 2 पसंद है और आपके पास हमेशा कुछ और प्रिंट करने का विकल्प होता है, जब यह
अपरिवर्तित

16

स्ट्रिंग का उपयोग करके लगता है (वर्णन करना: वैकल्पिक) सबसे सरल है।

डिफ़ॉल्ट मान ?? गैर-स्ट्रिंग्स जैसे इंट के लिए कोई मतलब नहीं है।
अगर 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 में अपडेट करने और बहुत सारे चेतावनी संदेश प्राप्त करने के बाद, मैं निम्नलिखित के साथ आया, जो मूल आउटपुट व्यवहार की तरह अधिक है, इसमें जोड़ना आसान है, कोड और आउटपुट दोनों में "स्ट्रिंग (वर्णन करना :)") का उपयोग करने की क्रिया को कम करता है ।

मूल रूप से, एक वैकल्पिक एक्सटेंशन जोड़ें जो स्ट्रिंग को वैकल्पिक में बात का वर्णन करता है, या बस "शून्य" यदि सेट नहीं है। इसके अलावा, अगर वैकल्पिक चीज़ स्ट्रिंग है, तो इसे उद्धरण में रखें।

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"

निम्नलिखित लिंक से मदद के लिए धन्यवाद:

चेक-अगर-चर-है-एक-वैकल्पिक और क्या-प्रकार यह wraps


यह समाधान वैकल्पिक श्रृंखला में काम नहीं कर रहा है। की तरह a?.b?.c.orNil
विन्सेन्ट बैठो

11

इसके लिए ओले बेगमेन का फिक्स देखें । मुझे यह पसंद है। यह एक ???ऑपरेटर बनाता है जिसे आप इस तरह उपयोग कर सकते हैं:

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
हां, मैं निल-
कॉलेस्सिंग

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))
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.