什么是Swift相当于 – ?

在Objective-C中,可以在其类中添加一个description方法来帮助debugging:

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

然后在debugging器中,你可以这样做:

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

Swift中的等价物是什么? Swift的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) 

相反,我必须明确地调用description:

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

有没有更好的办法?

通过一些实验,我发现PrintableDebugPrintable协议在编译实际应用程序时工作,但不在REPL或Playground中。

注意 :你写的代码是正确的,但在这种情况下,你可能正在寻找DebugPrintable


Swift已经将这些协议重命名为CustomStringConvertibleCustomDebugStringConvertible – 虽然编译器当前有帮助地告诉你它已经完成了:)

在Swift中使用CustomStringConvertibleCustomDebugStringConvertible协议的例子:

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或者基础库中包含的任何类inheritance,那么使它inheritanceNSObject类或者使它符合CustomStringConvertibleCustomDebugStringConvertible协议。

只需使用CustomStringConvertiblevar description: String { return "Some string" }

适用于Xcode 7.0testing版

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

有关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!" 
 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 
 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