如果我有下一种类型:
type Color(r: float, g: float, b:float) =
member this.r = r
member this.g = g
member this.b = b
static member ( * ) (c1:Color, c2:Color) =
Color (c1.r*c2.r, c1.g*c2.g, c1.b*c2.b)
static member Zero = Color(0.0,0.0,0.0)
Run Code Online (Sandbox Code Playgroud)
我这样做:
let ca = Color(1.,1.,1.)
let cb = Color(1.,1.,1.)
ca = cb
Run Code Online (Sandbox Code Playgroud)
我应该获得true,但是通过脚本进行的 F# 交互却给了我false 相反,如果我定义为:
let ca = Color(1.,1.,1.)
let cb = ca
ca = cb
Run Code Online (Sandbox Code Playgroud)
它返回true 我尝试以这种方式比较定义类型的两个值是否做错了什么?我怎样才能得到正确的结果?
谢谢
的OP定义Color是一个类。类具有引用相等性默认这意味着只有当它们字面上是同一个对象(指向相同的内存地址)时它们才相等。
只有 F# 中的函数数据类型具有结构相等性。其中包括记录、受歧视的工会、列表和一些其他类型。
Color定义为记录会更惯用:
type Color = { Red : float; Green : float; Blue : float }
Run Code Online (Sandbox Code Playgroud)
这种类型内置了结构平等:
> let ca = { Red = 1.; Green = 1.; Blue = 1. };;
val ca : Color = {Red = 1.0;
Green = 1.0;
Blue = 1.0;}
> let cb = { Red = 1.; Green = 1.; Blue = 1. };;
val cb : Color = {Red = 1.0;
Green = 1.0;
Blue = 1.0;}
> ca = cb;;
val it : bool = true
Run Code Online (Sandbox Code Playgroud)
如果你想为类型定义乘法和零,你也可以这样做:
let (*) x y = {
Red = x.Red * y.Red
Green = x.Green * y.Green
Blue = x.Blue * y.Blue }
let zero = { Red = 0.0; Green = 0.0; Blue = 0.0 }
Run Code Online (Sandbox Code Playgroud)
这使您能够编写,例如:
> let product = ca * cb;;
val product : Color = {Red = 1.0;
Green = 1.0;
Blue = 1.0;}
Run Code Online (Sandbox Code Playgroud)