Swift: Why does the CustomStringConvertible description run too many times in this case?

I tried this code on Xcode Playground and noticed that the gett method descriptiongot too many times.

Code here: https://gist.github.com/T-Pham/4b72d17851162a32b2fc534f0618135d

First with two lines print, the code runs 3176 times.

enter image description here

Then, when the first is printcommented out, the code runs 3164 times.

enter image description here

This means that the first printwas to run the code 12 times. Nonetheless,

enter image description here

used 148 times instead.

+4
source share
1 answer

This is a playground that is messing with your head.

, CustomStringConvertibe (, ).

, () .

, , :

 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 

, mirror(), , , , . mirror() Node:

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

 print(tree.mirror())

[EDIT] ( , ) :

 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
 }

:

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

:

 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
+4

Source: https://habr.com/ru/post/1648801/


All Articles