67

这似乎是某些类型的等价比较,但不是字符串。

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

这正如预期的那样。

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

为什么"odp" != "odp"评价为true?它实际上在做什么?它不应该产生类型错误吗?

4

5 回答 5

101

您已经体验到结构平等和物理平等之间的差异。

<>=(结构上的平等)一样!=,与==(物理上的平等)一样

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

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

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

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

编辑结构和物理平等何时等效

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

于 2009-09-11T18:54:19.603 回答
18

!=运算符的反义词是==运算符,而不是那个=

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

== 运算符是“物理相等”。当您键入 时 "a" == "a",您比较恰好看起来相似的两个不同的字符串实例false,因此运算符返回。虽然有一个实例使其返回 true:

# let str = "a"
  in str == str ;;
- : bool = true
# let str = "a"
  in str != str ;;
- : bool = false
于 2009-09-11T19:00:34.677 回答
14

除了已经提供的所有正确答案之外,还有关于 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

到目前为止,一切都很好:x并且t.(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物理相等是检测它们在结构上明显相等的快速方法,甚至不必递归和读取它们。那是:

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

如果你记住在 OCaml 中“布尔或”运算符是“惰性的”,

let equal t1 t1 =
  (t1 == t2) ||
  match ...
于 2009-09-13T09:24:24.343 回答
2

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

在这种情况下,"odp" = "odp" 因为它们是具有相同值的两个字符串!

所以它们不是==因为它们是两个不同的字符串存储在不同的(内存)位置

它们是=因为它们具有相同的字符串值

更深一步,“odp”是匿名变量。两个匿名变量导致这两个字符串。

为了您的方便:

# "odp" = "odp";; 
- : bool = true 
# "odp" != "odp";; 
- : bool = true 
# "odp" <> "odp";; 
- : bool = false
于 2013-06-25T09:40:58.740 回答
1

整数是唯一物理和结构相等性相同的类型,因为整数是唯一未装箱的类型

于 2009-09-11T19:06:12.027 回答