我需要了解一些关于F#非常重要的事情:它如何处理引用和值.我知道F#定义了不可变和可变对象,也知道了原因.
但有一件事我不知道:对象是如何处理的?
我的意思是,在C#中,一切都是指针,当为一个对象分配另一个的引用时,数据是相同的,我们将有两个指向相同数据的指针.
所以在C#中如果我有这个:
Object myobj1 = new Object();
Object myobj2 = myobj1;
bool myobj1 == myobj2; // It is true
Run Code Online (Sandbox Code Playgroud)
那么,f#怎么样?
let myvar: MyObj = new MyObj ()
let myvar2: MyObj = myvar
Run Code Online (Sandbox Code Playgroud)
这是什么情况?作业是否涉及复制?或不.
而且,一般来说,这个主题的f#方法是什么?(我的意思是价值与参考).
使用引用类型和值类型时,F#的行为与C#类似.
Struct属性声明)时,唯一值得注意的区别是标准F#类型(有区别的联合,记录,列表,数组和元组)具有结构相等的语义.这意味着它们通过比较存储在它们中的实际值而不是通过比较引用(即使它们是引用类型)进行比较.例如,如果您创建两个包含相同数据的元组列表:
> let l1 = [ ("Hello", 0); ("Hi", 1) ]
let l2 = [ ("Hi", 1); ("Hello", 0) ] |> List.rev;;
(...)
> l1 = l2;;
val it : bool = true
Run Code Online (Sandbox Code Playgroud)
true即使列表和元组是引用类型,也会得到.但是,如果你比较参考文献(编辑:添加样本灵感来自kvb):
> System.Object.ReferenceEquals(l1, l2);;
val it : bool = false
Run Code Online (Sandbox Code Playgroud)
在F#中使用结构相等是有意义的,因为类型是不可变的 - 当您创建包含相同数据的两个值时,它们将始终相同.如果它们是可变的,你可以改变它们并且它们将不再相等 - 这就是为什么使用引用相等来为可变类型更有意义.
正如您可以通过以下简单实验说服自己,F#的行为与C#的行为相同:
printfn "%b" (myvar = myvar2) // true
Run Code Online (Sandbox Code Playgroud)
或者更好的是:
printfn "%b" (obj.ReferenceEquals(myvar, myvar2)) // true
Run Code Online (Sandbox Code Playgroud)
因为托马斯指出,行为(=)可能有点微妙.
从我的角度来看,没有任何合理的选择; 还有什么myvar2可能含有?没有用于复制任意类型的对象任何一般性机制,这样才有意义的唯一行为是myvar和myvar2含有相等引用.