gpt4 book ai didi

Swift:为什么在这种情况下 CustomStringConvertible 描述运行了太多次?

转载 作者:搜寻专家 更新时间:2023-10-31 08:32:09 24 4
gpt4 key购买 nike

我在 Xcode Playground 中尝试这段代码并注意到 description getter 方法被调用了太多次。

代码在这里:https://gist.github.com/T-Pham/4b72d17851162a32b2fc534f0618135d

首先,print 行,代码运行了 3176 次。

enter image description here

然后注释掉第一个print,代码运行了3164次。

enter image description here

这意味着第一个 print 必须运行代码 12 次。然而,

enter image description here

反而是148次。

最佳答案

是 Playground 在搅乱你的头脑。

Playground 正在计算它自己对具有 CustomStringConvertibe 协议(protocol)的变量的调用(可能是为了在右侧面板上提供信息)。

如果您只是简单地调用 mirror(tree) 而根本不打印,您就可以看到这种情况。

如果你使用自己的计数器来计算实际的调用次数,它会给出截然不同的结果:

 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() 函数时遇到了一些困难,我认为递归的函数可能更容易理解。如何向 Node 添加一个 mirror() 函数:

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

print(tree.mirror())

[编辑] 这是一个结构更清晰的非递归镜像函数(与您的逻辑相同):

 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

关于Swift:为什么在这种情况下 CustomStringConvertible 描述运行了太多次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38529646/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com