鉴于函数式编程在尽可能坚持不可变变量时是最好的,并且 Ramda 总是进行浅拷贝,那么对象如何must在大多数纯功能框架中处理可变的问题?
例如,考虑 PIXI.Sprite(在 pixi.js 中)。显示系统具有链接在一起的固有层次结构,并且有自己的跟踪对象的方式,因此它可以重用纹理等。垃圾收集它们可能是一个真正的问题。
可以采取什么样的方法来处理这个问题(以及像钠打字稿这样强大的玻璃钢系统)?
具体来说,这种方法是否可以改进:
有某种 unsafePerformIO() 函数可以修改重对象。这些对象的所有修改只能通过该函数完成。
轻量级元信息对象承载所有逻辑。
那些轻量的信息对象直接引用重的对象
这是 Typescript 中的完整代码示例,用于演示其实际操作(只需导入 PIXI 和 Ramda)。关键行在 gameLoop() 中:
let app = new PIXI.Application(window.innerWidth, window.innerHeight);
document.body.appendChild(app.view);
let ball = new PIXI.Graphics();
ball.beginFill(0xFF0000);
ball.drawCircle(0,0,40);
ball.endFill();
ball.y = app.stage.height/2;
app.stage.addChild(ball); //app
let ticker = new PIXI.ticker.Ticker();
ticker.add(gameLoop);
ticker.start();
let ballReference = {
ptr: ball,
x: 0
}
function performUnsafeIO(reference) {
reference.ptr.x = reference.x;
}
function gameLoop(deltaTime:number) {
//this version breaks!
//ball = R.assoc('x', ball.position.x + deltaTime * 1, ball);
//This works fine... but are there any gotchas?
ballReference = R.assoc('x', ballReference.x + deltaTime * 1, ballReference);
performUnsafeIO(ballReference);
}
(注意,通过谷歌找到的这段对话是一个很好的参考点:https://web.archive.org/web/20100410001213/http://itmmetelko.com/blog/2008/02/23/tical-programming-immutable-objects-explained-irc-style/ https://web.archive.org/web/20100410001213/http://itmmetelko.com/blog/2008/02/23/functional-programming-immutable-objects-explained-irc-style/)