【问题标题】:Does != have meaning in OCaml?!= 在 OCaml 中有意义吗?
【发布时间】:2026-01-11 13:45:01
【问题描述】:

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

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

这符合预期。

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

为什么"odp" != "odp" 的计算结果为true?它实际上在做什么?它不应该产生类型错误吗?

【问题讨论】:

    标签: ocaml


    【解决方案1】:

    您已经体验过结构平等和物理平等之间的区别。

    &lt;&gt; 对应于=(结构相等)就像!= 对应于==(物理相等)

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

    是假的,因为每个都在不同的内存位置实例化,这样做:

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

    大多数时候你会想要使用=&lt;&gt;

    编辑关于何时结构和物理相等

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

    【讨论】:

      【解决方案2】:

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

      # "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
      

      【讨论】:

        【解决方案3】:

        除了已经提供的所有正确答案之外,还有关于 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 的物理相等性是一种快速检测它们在结构上明显相等的方法,甚至无需递归和读取它们。那就是:

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

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

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

        【讨论】:

          【解决方案4】:

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

          在这种情况下,"odp" = "odp" 因为它们是 TWO 具有 SAME VALUE 的字符串!!

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

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

          再深入一点,“odp”是匿名变量。而两个匿名变量导致了这个两个字符串。

          为了您的方便:

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

          【讨论】:

            【解决方案5】:

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

            【讨论】:

            • int 和 chars 是唯一的类型... FTFY
            • 为了缩短这个列表,它真的应该说任何整数,因为它还包括空列表和单位
            • ...以及任何经过哈希处理的内容。这样做正是为了让您可以用物理平等代替结构平等以提高性能。
            最近更新 更多