Swift中的通用飞锤模式
我正在尝试在Swift中实现一个通用的flyweight模式。在我的代码中,我使用弱引用字典来表示弱引用。基本协议(Swift中的通用飞锤模式,swift,flyweight-pattern,Swift,Flyweight Pattern,我正在尝试在Swift中实现一个通用的flyweight模式。在我的代码中,我使用弱引用字典来表示弱引用。基本协议(节点)只有一个位置。更改位置将创建一个新的节点 我在网上看到的实现在不再有任何对给定flyweight的引用时不会试图清理问题 符合节点的类可以使用维护现有对象字典的工厂选择加入flyweighting 当一个值被释放时,散列函数会发生变化(请参见Weak.hash(into:))。那会破坏一切吗 在deinit中取消这些值的所有权并以某种方式将其从工厂中删除是否更好?我可以用一
节点
)只有一个位置。更改位置将创建一个新的节点
我在网上看到的实现在不再有任何对给定flyweight的引用时不会试图清理问题
符合节点
的类可以使用维护现有对象字典的工厂
选择加入flyweighting
- 当一个值被释放时,散列函数会发生变化(请参见
)。那会破坏一切吗Weak.hash(into:)
- 在
中取消这些值的所有权并以某种方式将其从工厂中删除是否更好?我可以用一般的方法吗deinit
- 不能在协议类型上使用标识运算符
。我能在考试中绕过这个问题吗==
- 有没有更简单的方法
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!")
<代码>导入基础
协议节点{
//不可变:更改位置将返回一个新节点
func位置(p:CGPoint)->节点
func printAddress()
}
协议HashableNode:类,Hashable,节点{}
结构弱:可散列{
静态函数==(左:弱,右:弱)->Bool{
返回lhs.value==rhs.value
}
弱var值:T?
func散列(放入散列程序:inout散列程序){
值?.hash(放入:&hasher)
}
}
阶级工厂{
var值=[弱:弱]()
func make(u-proto:T)->T{
设w=弱(值:proto)
如果设v=值[w]{
如果让r=v.value{
返回r
}
}
值[w]=w
返回原型
}
}
类TestNode:HashableNode{
脱硝{
打印(“TestNode Denit”)
}
//我可以自动定义相等和散列吗?
静态函数==(lhs:TestNode,rhs:TestNode)->Bool{
返回lhs.p==rhs.p
}
func散列(放入散列程序:inout散列程序){
联合散列器(p.x)
联合收割机(p.y)
}
设p:CGPoint
初始(p:CGPoint){
打印(“TestNode init”)
self.p=p
}
func位置(p:CGPoint)->节点{
返回testNodeFactory.make(TestNode(p:p))
}
func printAddress(){
打印(Unmanaged.passUnretained(self.toOpaque())
}
}
设testNodeFactory=Factory()
func runTest(){
设n0=testNodeFactory.make(TestNode(p:CGPoint.zero))
设n1=testNodeFactory.make(TestNode(p:CGPoint.zero))
断言(n0==n1)
n0.printAddress()
n1.打印地址()
设n2=n0位置(CGPoint(x:1,y:1))
n2.打印地址()
//不编译:
//二进制运算符“!==”不能应用于“Node”和“TestNode”类型的操作数
//断言(n2!==n0)
}
运行测试()
打印(“完成!”)
此行:
let n2 = n0.position(CGPoint(x: 1, y: 1))
这里调用的position方法是返回一个节点,而不是为n1
和n2
显式创建的TestNode
。编译器不知道如何比较这两种类型
您可以为TestNodeNode实现Comparable
,也可以将n2类型转换为TestNode我担心会出现yeilds错误:类型“TestNode”不符合协议“Node”是的,我只是回来更改这个。我相信你会有“添加为”?将TestNode添加到值分配。很抱歉,我现在不在电脑旁。很高兴我能帮忙!