在OCaml中有!=有意义吗?

这似乎是一些types的等价比较,但不是string。

# 3 != 3;; - : bool = false # 3 != 2;; - : bool = true 

这是预期的。

 # "odp" = "odp";; - : bool = true # "odp" != "odp";; - : bool = true # "odp" <> "odp";; - : bool = false 

为什么"odp" != "odp"评估为true ? 它究竟在做什么? 它不应该产生一个types错误?

你经历了结构和物质平等之间的差异。

<> = is to = (structural equality)as != is == (physical equality)

 "odg" = "odg" (* true *) "odg" == "odg" (* false *) 

是错误的,因为每个实例化在不同的内存位置,做:

 let v = "odg" v == v (* true *) v = v (* true *) 

大多数时候你会想要使用=<>

编辑关于何时结构和物理上的平等是等价的

你可以使用what_is_it函数 ,找出所有在结构和物理上都相等的types。 正如在下面的评论和链接的文章中所提到的,字符,整数,单位,空列表和变体types的一些实例将具有该属性。

!=运算符的反义词是==运算符,而不是= 1。

 # "a" != "a" ;; - : bool = true # "a" == "a" ;; - : bool = false 

==运算符是一个“物理平等”。 当你键入"a" == "a" ,你比较两个看起来相似的string的不同实例 ,所以运算符返回false 。 有一个实例会使其返回true:

 # let str = "a" in str == str ;; - : bool = true # let str = "a" in str != str ;; - : bool = false 

关于OCaml中==!=快速解释,以及已经提供的所有正确答案:

1 / ==!=公开你实际上不想知道的实现细节。 例:

 # let x = Some [] ;; val x : 'a list option = Some [] # let t = Array.create 1 x ;; val t : '_a list option array = [|Some []|] # x == t.(0) ;; - : bool = true 

到目前为止,这么好: xt.(0)在物理上是相等的,因为t.(0)包含一个指向x所指向的同一块的指针。 这是执行的基本知识所要求的。 但:

 # let x = 1.125 ;; val x : float = 1.125 # let t = Array.create 1 x ;; val t : float array = [|1.125|] # x == t.(0) ;; - : bool = false 

你在这里看到的是一个涉及浮点数的其他有用的优化的结果。

2 /另一方面,有一个安全的方式来使用== ,这是一个快速,但不完整的方法来检查结构的平等。

如果你在二叉树上写一个相等函数

 let equal t1 t2 = match ... 

检查t1t2是否物理平等是一种快速检测结构明显相等的方法,甚至不需要recursion和读取。 那是:

 let equal t1 t2 = if t1 == t2 then true else match ... 

如果你记住,在OCaml中,“boolean or”操作符是“懒惰”的,

 let equal t1 t1 = (t1 == t2) || match ... 

他们就像你们class的两个“汤姆”! 因为:

在这种情况下, "odp" = "odp"因为它们是相同的 两个string值!!

所以他们不是==因为他们是两个不同的string存储在不同的 (内存) 位置

他们是=因为他们有相同的string值

再深一步,“odp”就是匿名variables。 而两个匿名variables导致这两个string。

为了您的方便:

 # "odp" = "odp";; - : bool = true # "odp" != "odp";; - : bool = true # "odp" <> "odp";; - : bool = false 

整数是物理和结构相等的唯一types,因为整数是唯一被拆箱的types