type Tag(Kids) =
member this.Kids = Kids
static member (-) (this: Tag, that: list<obj>) =
Tag(that::this.Kids)
Run Code Online (Sandbox Code Playgroud)
此代码的要点是基于现有对象构造新对象,但修改对象上的一个(或多个)字段.基本上,它是thing.setX(...)mutator方法的代理,除了使用不可变数据.
它看起来非常丑陋和冗长,我确信在保持数据的不变性的同时必须有更好的方法,但我还没弄清楚如何.这有什么语法上很好的方法吗?
编辑:为了清楚起见,我还在层次结构中有其他类:
type HTMLTag(s, Classes, Kids, Styles) =
inherit Tag(Kids)
member this.NominalTag = s
member this.Classes = Classes
member this.Styles: list<String * String> = Styles
static member (-) (this: HTMLTag, that: list<obj>) =
HTMLTag(this.NominalTag, this.Classes, that::this.Kids, this.Styles)
Run Code Online (Sandbox Code Playgroud)
除了它非常冗长之外,-函数的"复制与修改"的东西完全是非泛型的:即使我每次都做同样的事情(复制w /修改为同一个变量)我还要重写整个事情,这不是很好.
我发现非常讨厌的一件事是变异非常简单:
static member (-) (this: Tag, that: list<obj>) =
this.Kids = that :: this.Kids
this
Run Code Online (Sandbox Code Playgroud)
但我试图尽可能保持一切不变
复制和更新记录表达式[MSDN]旨在处理这种确切的情况.如果您可以使用记录类型,则可以执行此操作
type Tag =
{ NominalTag : obj
Classes : obj
Kids : list<obj>
Styles : list<String * String> }
static member (-) (this: Tag, that: list<obj>) =
{ this with Kids = this.Kids @ that }
Run Code Online (Sandbox Code Playgroud)
此代码的编译形式与您的代码几乎完全相同.
顺便说一句,(-)操作员被用来追加是奇怪的......但我认为这是一个人为的例子.
现在您已经更新了问题,我对您想要做的事感到困惑.如果你想返回一个新对象,我看不到变异如何帮助你.
更具功能性的方法(vs继承)是分离数据和行为,数据是记录和模块中分组的行为功能.如果希望跨类型共享行为,请使用接口.记录可以实现接口.
| 归档时间: |
|
| 查看次数: |
267 次 |
| 最近记录: |