简体   繁体   English

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

[英]Why are MonoGame's Rectangle class fields immutable in F#?

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

The second line fails in F#, but in C# the assignment works. 第二行在F#中失败,但在C#中,赋值有效。 I am not sure why. 我不知道为什么。

Rectangle is a struct rather than a class. Rectangle是一个结构而不是一个类。 You can have that line work as you'd expect if you mark the value with mutable : 如果使用mutable标记值,则可以按预期运行该行:

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

This is actually quite interesting, as F# makes the value-type semantics of structs more visible compared to what C# does. 这实际上非常有趣,因为与C#相比,F#使结构的值类型语义更加明显。

rect.X <- 888 does not really mutate the field, rather it updates rect with a new value of the struct with the X field modified. rect.X <- 888并没有真正改变字段,而是使用修改了X字段的struct的新值更新rect So you can imagine it does an equivalent of rect <- { rect with X = 888 } . 所以你可以想象它确实相当于rect <- { rect with X = 888 } At that point it's quite clear why the compiler wants to see mutable there. 在那一点上,很清楚为什么编译器想要在那里看到mutable

I wonder why F# designers didn't prohibit assignment syntax for structs and go with something similar to the record syntax. 我想知道为什么F#设计者没有禁止结构的赋值语法,并且使用类似于记录语法的东西。 Probably they didn't want to make it too different compared to C#. 可能他们不想让它与C#相比有太大的不同。

As the compiler is probably saying, 正如编译器可能会说的那样,

A value must be mutable in order to mutate the contents or take the address of a value type, eg 'let mutable x = ...' 值必须是可变的才能改变内容或获取值类型的地址,例如'let mutable x = ...'

In F#, let creates an immutable variable (ie a value). 在F#中, let创建一个不可变的变量(即一个值)。 The compiler enforces this by not letting you mutate it. 编译器强制执行此操作,不允许您改变它。 You must write let mutable to get an equivalent variable declaration to what you had in C#. 你必须编写let mutable来获得与C#中相同的变量声明。

Note that if Rectangle was a reference type, F# wouldn't complain, because you'd be modifying what is referenced by the value, not the value itself. 请注意,如果Rectangle是引用类型,则F#不会抱怨,因为您将修改值引用的内容,而不是值本身。 In the case of a value type (like Mono's Rectangle), the identifier bound to the value is the value itself, so you cannot mutate it. 在值类型(如Mono的Rectangle)的情况下,绑定到值的标识符是值本身,因此您不能改变它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM