似乎是某些类型的等效比较,但不是字符串。
# 3 != 3;;
- : bool = false
# 3 != 2;;
- : bool = true
这是预期的。
# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false
为什么"odp" != "odp"
评估为true
?它到底在做什么?它不应该生成类型错误吗?
答案 0 :(得分:89)
你已经体验到了结构和身体平等之间的差异。
<>
是=
(结构相等),因为!=
是==
(物理相等)
"odg" = "odg" (* true *)
"odg" == "odg" (* false *)
为false,因为每个都在不同的内存位置实例化,执行:
let v = "odg"
v == v (* true *)
v = v (* true *)
大多数情况下,您都希望使用=
和<>
。
编辑结构和物理相等的时间:
您可以使用what_is_it function找出在结构和物理上都相同的所有类型。如下面的评论中所述,在链接文章中,字符,整数,单位,空列表和变体类型的某些实例将具有此属性。
答案 1 :(得分:16)
!=
运算符的反面是==
运算符,而不是=
运算符。
# "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
答案 2 :(得分:12)
除了已经提供的所有正确答案外,还简要说明了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 ...
检查t1
和t2
物理相等是一种快速的方法来检测它们在结构上是否相等,甚至不必递归和读取它们。那就是:
let equal t1 t2 =
if t1 == t2
then true
else
match ...
如果你记住在OCaml中“布尔或”运算符是“懒惰的”,
let equal t1 t1 =
(t1 == t2) ||
match ...
答案 3 :(得分:2)
他们就像你班上的两个“汤姆”!这是因为:
在这种情况下,"odp" = "odp"
因为它们是两个字符串 SAME VALUE !!
所以他们不是==
,因为他们两个不同的字符串存储在不同(内存)位置
它们是=
,因为它们具有相同的字符串值。
再深一步,“odp”是匿名变量。两个匿名变量导致这个两个字符串。
为方便起见:
# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false
答案 4 :(得分:0)
整数是物理和结构相等相同的唯一类型,因为整数是唯一未拆箱的类型