gpt4 book ai didi

swift - Swift 中的通用享元模式

转载 作者:搜寻专家 更新时间:2023-11-01 06:50:59 25 4
gpt4 key购买 nike

我正在尝试在 Swift 中实现通用享元模式。在我的代码中,我使用了弱引用字典。基本协议(protocol)(Node)只有一个位置。更改位置会创建一个新的 Node .

当不再有任何对给定享元的引用时,我在网上看到的实现不会尝试清理内容。

类符合 Node可以使用 Factory 选择加入享元法,它维护现有对象的字典。

  • 当一个值被释放时,散列函数会改变(参见 Weak<T>.hash(into:) )。这会破坏东西吗?
  • 值是无主的,并以某种方式从 deinit 中的工厂中删除会更好吗? ?我可以用通用的方式做到这一点吗?
  • 身份运算符 ===不能用于协议(protocol)类型。我可以在测试中以某种方式解决这个问题吗?
  • 有没有更简单的方法来做到这一点?

完整的 playground 代码

import Foundation

protocol Node {
// Immutable: changing the position returns a new node
func position(_ p:CGPoint) -> Node
func printAddress()
}

protocol HashableNode : class, Hashable, Node { }

struct Weak<T : HashableNode> : Hashable {
static func == (lhs: Weak<T>, rhs: Weak<T>) -> Bool {
return lhs.value == rhs.value
}

weak var value : T?

func hash(into hasher: inout Hasher) {
value?.hash(into: &hasher)
}
}

class Factory<T:HashableNode> {
var values = [Weak<T> : Weak<T>]()

func make(_ proto: T) -> T {
let w = Weak<T>(value: proto)
if let v = values[w] {
if let r = v.value {
return r
}
}
values[w] = w
return proto
}
}

class TestNode : HashableNode {

deinit {
print("TestNode deinit")
}

// Can I define equality and hash automatically?
static func == (lhs: TestNode, rhs: TestNode) -> Bool {
return lhs.p == rhs.p
}

func hash(into hasher: inout Hasher) {
hasher.combine(p.x)
hasher.combine(p.y)
}


let p:CGPoint

init(p: CGPoint) {
print("TestNode init")
self.p = p
}

func position(_ p: CGPoint) -> Node {
return testNodeFactory.make(TestNode(p: p))
}

func printAddress() {
print(Unmanaged.passUnretained(self).toOpaque())
}

}

let testNodeFactory = Factory<TestNode>()

func runTest() {

let n0 = testNodeFactory.make(TestNode(p: CGPoint.zero))
let n1 = testNodeFactory.make(TestNode(p: CGPoint.zero))

assert(n0 === n1)

n0.printAddress()
n1.printAddress()

let n2 = n0.position(CGPoint(x: 1, y: 1))

n2.printAddress()

// Doesn't compile:
// Binary operator '!==' cannot be applied to operands of type 'Node' and 'TestNode'
// assert(n2 !== n0)

}

runTest()
print("done!")

最佳答案

这一行:

let n2 = n0.position(CGPoint(x: 1, y: 1))

此处调用的位置方法返回的是 Node,而不是您为 n1 显式创建的 TestNode n2。编译器不知道如何比较这两种类型。

您可以为 TestNode<->Node 实现 Comparable 或将 n2 类型转换为 TestNode

关于swift - Swift 中的通用享元模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57085429/

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