作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试在 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/
据我所知,对象池是一种创建模式,享元是一种结构模式,但实际上我看不出两者之间有太大区别。有人可以向我解释它们之间的区别以及每种方法在实现中何时有用吗? 最佳答案 一个区别在于享元通常是不可变的实例,而
字符串已经在使用享元设计模式。汇集常见的 String 对象是否有益/性能好?因为字符串已经从字符串池中提取出来了吗? 最佳答案 字符串可以来自很多地方,默认情况下只有字符串文字在字符串池中。例如,当
我是一名优秀的程序员,十分优秀!