स्विफ्ट किसके समकक्ष है - [NSObject विवरण]?


163

ऑब्जेक्टिव-सी में, कोई descriptionडिबगिंग में सहायता करने के लिए अपनी कक्षा में एक विधि जोड़ सकता है :

@implementation MyClass
- (NSString *)description
{
    return [NSString stringWithFormat:@"<%@: %p, foo = %@>", [self class], foo _foo];
}
@end

फिर डिबगर में, आप कर सकते हैं:

po fooClass
<MyClass: 0x12938004, foo = "bar">

स्विफ्ट में समतुल्य क्या है? स्विफ्ट का REPL आउटपुट मददगार हो सकता है:

  1> class MyClass { let foo = 42 }
  2> 
  3> let x = MyClass()
x: MyClass = {
  foo = 42
}

लेकिन मैं कंसोल पर मुद्रण के लिए इस व्यवहार को ओवरराइड करना चाहता हूं:

  4> println("x = \(x)")
x = C11lldb_expr_07MyClass (has 1 child)

क्या इस printlnआउटपुट को साफ करने का कोई तरीका है ? मैंने Printableप्रोटोकॉल देखा है:

/// This protocol should be adopted by types that wish to customize their
/// textual representation.  This textual representation is used when objects
/// are written to an `OutputStream`.
protocol Printable {
    var description: String { get }
}

मुझे लगा कि यह स्वचालित रूप से "देखा" जाएगा, printlnलेकिन ऐसा प्रतीत नहीं होता है:

  1> class MyClass: Printable {
  2.     let foo = 42
  3.     var description: String { get { return "MyClass, foo = \(foo)" } }
  4. }   
  5> 
  6> let x = MyClass()
x: MyClass = {
  foo = 42
}
  7> println("x = \(x)")
x = C11lldb_expr_07MyClass (has 1 child)

और इसके बजाय मुझे स्पष्ट रूप से वर्णन करना होगा:

 8> println("x = \(x.description)")
x = MyClass, foo = 42

क्या कोई बेहतर तरीका है?

जवाबों:


124

एक स्विफ्ट प्रकार पर इसे लागू करने के लिए आपको CustomStringConvertibleप्रोटोकॉल को लागू करना होगा और फिर एक स्ट्रिंग गुण भी बुलाया जाना चाहिए description

उदाहरण के लिए:

class MyClass: CustomStringConvertible {
    let foo = 42

    var description: String {
        return "<\(type(of: self)): foo = \(foo)>"
    }
}

print(MyClass()) // prints: <MyClass: foo = 42>

नोट: type(of: self)स्पष्ट रूप से 'MyClass' लिखने के बजाय वर्तमान उदाहरणों का प्रकार मिलता है।


3
शानदार खोज! मैं "स्विफ्ट-आई सैंपल.स्विफ़्ट" और "स्विफ़्ट सैंपल.स्वफ़्ट एंड& सैंपल" के प्रिंटार रडार आउटपुट को अलग करने जा रहा हूँ।
जेसन

उस पर जानकारी के लिए धन्यवाद। मैं एक खेल के मैदान में प्रिंट करने योग्य कोशिश कर रहा था और वास्तव में यह अभी काम नहीं करता है। अच्छा है यह एक ऐप में काम करता है।
टॉड कनिंघम

मुद्रण योग्य खेल के मैदान में काम करता है, लेकिन अगर NSObject से कक्षा उतरती है
dar512

5
Swift 2.0 में यह CustomStringConvertible और CustomDebugStringConvertible में बदल गया है
माइक वॉसलर सेप

इसके अलावा, Xcode 7.2 के साथ खेल के मैदान में CustomStringConvertible और CustomDebugStringConvertible का उपयोग करने में कोई समस्या नहीं है
निकोलस क्रेडली

54

स्विफ्ट में उपयोग CustomStringConvertibleऔर CustomDebugStringConvertibleप्रोटोकॉल का उदाहरण :

PageContentViewController.swift

import UIKit

class PageContentViewController: UIViewController {

    var pageIndex : Int = 0

    override var description : String { 
        return "**** PageContentViewController\npageIndex equals \(pageIndex) ****\n" 
    }

    override var debugDescription : String { 
        return "---- PageContentViewController\npageIndex equals \(pageIndex) ----\n" 
    }

            ...
}

ViewController.swift

import UIKit

class ViewController: UIViewController
{

    /*
        Called after the controller's view is loaded into memory.
    */
    override func viewDidLoad() {
        super.viewDidLoad()

        let myPageContentViewController = self.storyboard!.instantiateViewControllerWithIdentifier("A") as! PageContentViewController
        print(myPageContentViewController)       
        print(myPageContentViewController.description)
        print(myPageContentViewController.debugDescription)
    }

          ...
}

जो प्रिंट आउट:

**** PageContentViewController
pageIndex equals 0 ****

**** PageContentViewController
pageIndex equals 0 ****

---- PageContentViewController
pageIndex equals 0 ----

नोट: यदि आपके पास एक कस्टम वर्ग है जो UIKit या Foundation पुस्तकालयों में शामिल किसी भी वर्ग से विरासत में नहीं मिला है , तो इसे NSObjectवर्ग का वारिस बनाएं या इसे CustomStringConvertibleऔर CustomDebugStringConvertibleप्रोटोकॉल के अनुरूप बनाएं ।


समारोह को सार्वजनिक रूप से घोषित किया जाना चाहिए
Karsten

35

बस उपयोग CustomStringConvertibleऔरvar description: String { return "Some string" }

Xcode 7.0 बीटा में काम करता है

class MyClass: CustomStringConvertible {
  var string: String?


  var description: String {
     //return "MyClass \(string)"
     return "\(self.dynamicType)"
  }
}

var myClass = MyClass()  // this line outputs MyClass nil

// and of course 
print("\(myClass)")

// Use this newer versions of Xcode
var description: String {
    //return "MyClass \(string)"
    return "\(type(of: self))"
}

20

संबंधित उत्तर CustomStringConvertibleजाने का तरीका है। व्यक्तिगत रूप से, वर्ग (या संरचना) की परिभाषा को यथासंभव साफ रखने के लिए, मैं विवरण कोड को एक अलग एक्सटेंशन में भी अलग करूंगा:

class foo {
    // Just the basic foo class stuff.
    var bar = "Humbug!"
}

extension foo: CustomStringConvertible {
    var description: String {
        return bar
    }
}

let xmas = foo()
print(xmas)  // Prints "Humbug!"

8
class SomeBaseClass: CustomStringConvertible {

    //private var string: String = "SomeBaseClass"

    var description: String {
        return "\(self.dynamicType)"
    }

    // Use this in newer versions of Xcode
    var description: String {
        return "\(type(of: self))"
    }

}

class SomeSubClass: SomeBaseClass {
    // If needed one can override description here

}


var mySomeBaseClass = SomeBaseClass()
// Outputs SomeBaseClass
var mySomeSubClass = SomeSubClass()
// Outputs SomeSubClass
var myOtherBaseClass = SomeSubClass()
// Outputs SomeSubClass

6

जैसा कि यहां बताया गया है , आप इस विस्तार का उपयोग करके अपनी कक्षाओं को अपना विवरण बनाने के लिए स्विफ्ट की प्रतिबिंब क्षमताओं का उपयोग कर सकते हैं:

extension CustomStringConvertible {
    var description : String {
        var description: String = "\(type(of: self)){ "
        let selfMirror = Mirror(reflecting: self)
        for child in selfMirror.children {
            if let propertyName = child.label {
                description += "\(propertyName): \(child.value), "
            }
        }
        description = String(description.dropLast(2))
        description += " }"
        return description
    }
}

4
struct WorldPeace: CustomStringConvertible {
    let yearStart: Int
    let yearStop: Int

    var description: String {
        return "\(yearStart)-\(yearStop)"
    }
}

let wp = WorldPeace(yearStart: 2020, yearStop: 2040)
print("world peace: \(wp)")

// outputs:
// world peace: 2020-2040
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.