Swift eşdeğeri nedir - [NSObject description]?


163

Objective-C'de descriptionhata ayıklamaya yardımcı olmak için sınıflarına bir yöntem eklenebilir :

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

Sonra hata ayıklayıcıda şunları yapabilirsiniz:

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

Swift'in eşdeğeri nedir? Swift'in REPL çıktısı yardımcı olabilir:

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

Ancak konsola yazdırmak için bu davranışı geçersiz kılmak istiyorum:

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

Bu printlnçıktıyı temizlemenin bir yolu var mı ? PrintableProtokolü gördüm :

/// 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 }
}

Ben bu tarafından otomatik olarak "görüleceğini" düşündüm printlnama böyle görünmüyor:

  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)

Ve bunun yerine açıkça açıklama çağırmak zorunda:

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

Daha iyi bir yol var mı?

Yanıtlar:


124

Bunu bir Swift türünde uygulamak için CustomStringConvertibleprotokolü uygulamalı ve sonra da adlı bir dize özelliği uygulamalısınız description.

Örneğin:

class MyClass: CustomStringConvertible {
    let foo = 42

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

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

Not: type(of: self)açıkça 'Sınıfım' yazmak yerine geçerli örneklerin türünü alır.


3
Büyük bulmak! Bir radar - "swift -i sample.swift" ve "swift sample.swift && sample" çıktılarının println çıktısını değiştireceğim.
Jason

Bununla ilgili bilgi için teşekkürler. Yazdırılabilir bir oyun alanında deniyordum ve aslında şu anda çalışmıyor. İyi bir app çalışır duymak.
Tod Cunningham

Yazdırılabilir oyun alanında çalışır, ancak sınıf NSObject'ten
inerse

5
Swift 2.0'da
CustomStringConvertible

Ayrıca, Xcode 7.2 ile Oyun
Alanında CustomStringConvertible

54

Swift'te kullanım CustomStringConvertibleve CustomDebugStringConvertibleprotokol örneği :

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)
    }

          ...
}

Hangi çıktı:

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

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

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

Not: UIKit veya Foundation kütüphanelerinde bulunan herhangi bir sınıftan miras almayan özel bir sınıfınız varsa, sınıfın mirasını almasını veya protokollere ve protokollere NSObjectuymasını sağlayın .CustomStringConvertibleCustomDebugStringConvertible


fonksiyonun herkese açık olarak beyan edilmesi gerekir
Karsten

35

Sadece kullanın CustomStringConvertiblevevar description: String { return "Some string" }

Xcode 7.0 beta sürümünde çalışır

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

İle ilgili cevaplar CustomStringConvertiblegidilecek yoldur. Şahsen, sınıf (veya struct) tanımını olabildiğince temiz tutmak için, açıklama kodunu ayrı bir uzantıya ayırırım:

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

Açıklandığı gibi burada , ayrıca bu uzantıyı kullanarak sınıfları kendi tanımını oluşturmak yapmak Swift'in yansıma özelliklerini kullanabilirsiniz:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.