F#中不允许写入结构记录的可变属性。为什么?
当我有以下代码时:F#中不允许写入结构记录的可变属性。为什么?,f#,F#,当我有以下代码时: [<Struct>] type Person = { mutable FirstName:string ; LastName : string} let john = { FirstName = "John"; LastName = "Connor"} john.FirstName <- "Sarah"; [] 类型Person={mutable FirstName:string;LastName:string} 让john={FirstName=“j
[<Struct>]
type Person = { mutable FirstName:string ; LastName : string}
let john = { FirstName = "John"; LastName = "Connor"}
john.FirstName <- "Sarah";
[]
类型Person={mutable FirstName:string;LastName:string}
让john={FirstName=“john”;LastName=“Connor”}
john.FirstName这可以保护您免受几年前困扰C
世界的陷阱:结构是按值传递的
请注意,红色的波形(如果您在IDE中)不会出现在FirstName
下,而是出现在john
下。编译器抱怨的不是更改john.FirstName
的值,而是更改john
本身的值
对于非结构,引用和被引用对象之间有一个重要的区别:
引用和对象本身都是可变的。这样,您既可以修改引用(即使其指向不同的对象),也可以修改对象(即更改其字段的内容)
但是,对于结构,这种区别并不存在,因为没有引用:
这意味着当你变异john.FirstName
时,你也会变异john
本身。他们是同一个人
因此,为了执行此变异,您需要将john
本身声明为可变的:
[<Struct>]
type Person = { mutable FirstName:string ; LastName : string}
let mutable john = { FirstName = "John"; LastName = "Connor"}
john.FirstName <- "Sarah" // <-- works fine now
IDE将在c.Person
下面加下划线,告诉您“不能修改'SomeClass.Person'的返回值,因为它不是一个变量”
为什么呢?每次编写c.Person
,都会转换为调用属性getter,这就像另一个返回Person
的方法一样。但是因为Person
是通过值传递的,所以返回的Person
每次都是不同的Person
。getter不能返回对同一对象的引用,因为不能有对结构的引用。因此,对该返回值所做的任何更改都不会反映在居住在SomeClass
中的原始Person
中
在这个有用的编译器错误出现之前,很多人都会这样做:
c.Person.FirstName = "Jack"; // Why the F doesn't it change? Must be compiler bug!
我清楚地记得几乎每天都回答这个问题。那些日子真是太好了!:-)
c.Person.FirstName = "Jack"; // Why the F doesn't it change? Must be compiler bug!