为什么MonoGame的Rectangle类字段在F#中是不可变的?

时间:2016-01-19 19:50:37

标签: f# monogame

    let rect = new Rectangle(x, y, sprite.Width, sprite.Height)
    rect.X <- 888

第二行在F#中失败,但在C#中,分配有效。我不知道为什么。

2 个答案:

答案 0 :(得分:9)

Rectangle是结构而不是类。如果您使用mutable标记值,则可以按照您的预期运行该行:

let mutable rect = new Rectangle(10, 21, 10, 21)
rect.X <- 888

这实际上非常有趣,因为与C#相比,F#使结构的值类型语义更加明显。

rect.X <- 888并没有真正改变字段,而是使用修改了X字段的结构的新值更新rect。所以你可以想象它相当于rect <- { rect with X = 888 }。那时,很清楚为什么编译器想要在那里看到mutable

我想知道为什么F#设计师没有禁止结构的赋值语法,并且使用类似于记录语法的东西。可能他们并不想让它与C#相比有太大的不同。

答案 1 :(得分:3)

正如编译器可能会说的那样,

  

值必须是可变的才能改变内容或取出   值类型的地址,例如&#39;让mutable x = ...&#39;

在F#中,let创建一个不可变的变量(即一个值)。编译器强制执行此操作,不允许您改变它。您必须编写let mutable以获得与C#中的相同的变量声明。

请注意,如果Rectangle是引用类型,F#不会抱怨,因为您要修改值引用的内容,而不是值本身。对于值类型(如Mono的Rectangle),绑定到该值的标识符是值本身,因此您不能对其进行变异。