2016-07-22 10 views
4

Ich habe diesen Code in Xcode Playground versucht und festgestellt, dass die description Getter-Methode zu oft aufgerufen wurde.Swift: Warum wird die CustomStringConvertible-Beschreibung in diesem Fall zu oft ausgeführt?

Der Code ist hier: https://gist.github.com/T-Pham/4b72d17851162a32b2fc534f0618135d

Zuerst mit beiden print Linien, wird der Code 3176-mal ausgeführt werden.

enter image description here

dann mit den ersten print Kommentar gesetzt, wird der Code 3164-mal ausgeführt werden.

enter image description here

Das bedeutet, dass die erste print würde der Code 12-mal laufen haben. jedoch

enter image description here

es ist statt 148 mal.

Antwort

4

Es ist der Spielplatz, der mit Ihrem Kopf spielt.

Playground zählt eigene Aufrufe für Variablen, die über das CustomStringContibe-Protokoll verfügen (wahrscheinlich, um die Informationen auf der rechten Seite einzufügen).

Sie können dies sehen, wenn Sie einfach Spiegel (Baum) aufrufen, ohne überhaupt zu drucken.

Wenn Sie die tatsächliche Anzahl von Anrufungen mit Ihrem eigenen Zähler zählen, wird es ein ganz anderes Ergebnis geben:

var descCount = 0 
extension Node: CustomStringConvertible { 
    var description: String 
    { 
     descCount += 1 
     return "id: \(id)\nleft: \(left)\nright: \(right)" 
    } 
} 

descCount = 0 
print(tree) 
descCount // 12 

descCount = 0 
print(mirror(tree)) 
descCount // 12 

By the way, ich hatte ein wenig Schwierigkeiten zu verstehen, den Spiegel() Funktion und ich dachte, ein rekursiver wäre wahrscheinlich einfacher zu verstehen. Wie wäre es einen Spiegel() Funktion zu Knoten hinzufügen:

func mirror() -> Node 
{ 
    let result = Node() 
    result.id  = id 
    result.left = right?.mirror() 
    result.right = left?.mirror() 
    return result 
} 

print(tree.mirror()) 

[EDIT] Hier ist eine nicht-rekursive Spiegelfunktion (gleiche Logik wie bei Ihnen) mit einer etwas klareren Struktur:

func mirror2(tree:Node) -> Node 
{ 
    // will return top of mirrored tree 
    let newTree = Node() 

    // node pair used for traversal and duplication 
    var original:Node! = tree 
    var mirrored:Node! = newTree 

    // traversal of tree structure left side first 
    // (uses mirrored tree to keep track of traversed nodes) 
    while original != nil 
    { 
     // carry node identifier (and contents eventually) 
     mirrored.id = original.id 

     // downwards, mirror left side first (if not already done) 
     if (original.left == nil) != (mirrored.right == nil) 
     { 
      original  = original.left 
      mirrored.right = Node() 
      mirrored  = mirrored.right 
      continue  
     } 

     // downwards, mirror right side second (if not already done) 
     if (original.right == nil) != (mirrored.left == nil) 
     { 
      original  = original.right 
      mirrored.left = Node() 
      mirrored  = mirrored.left 
      continue 
     } 

     // upwards from leaves and completed branches 
     original = original.parent 
     mirrored = mirrored.parent 
    } 
    return newTree 
} 

und einige visuelle Süßigkeiten für Baum Beschreibungen:

extension Node: CustomStringConvertible 
{ 
    var indent:String 
    { return " " + (parent?.indent ?? "") } 
    var description: String 
    { 
     return "\(id)\n" 
       + (left != nil ? "\(indent)L:\(left!)" : "") 
       + (right != nil ? "\(indent)R:\(right!)" : "") 
    } 
} 

in einem einfacheren Vergleich der Ergebnisse resultierende:

print(tree) 

// 0 
// L:1 
//  L:3 
//  L:7 
//  R:8 
//  R:4 
//  L:9 
//  R:10 
// R:2 
//  R:6 
//  L:13 
//  R:14 
// 

print(mirror2(tree)) 

// 0 
// L:2 
//  L:6 
//  L:14 
//  R:13 
// R:1 
//  L:4 
//  L:10 
//  R:9 
//  R:3 
//  L:8 
//  R:7 
+0

Dank @Alain T .. Über die Mirror-Funktion, die Gist ist über die Implementierung es ohne Rekursion, deshalb ist: D –