代码之家  ›  专栏  ›  技术社区  ›  fluency03

正则表达式模式相等

  •  5
  • fluency03  · 技术社区  · 7 年前

    在ScalaTest中,我有以下检查:

    "abc".r shouldBe "abc".r
    

    但这是不平等的。我不明白。

    abc was not equal to abc
    ScalaTestFailureLocation: com.ing.cybrct.flink.clickstream.ConfigsTest$$anonfun$6 at (ConfigsTest.scala:97)
    Expected :abc
    Actual   :abc
    
    3 回复  |  直到 7 年前
        1
  •  9
  •   Andrey Tyukin    7 年前

    当它是 possible to decide whether two regular expressions accept the same language ,它看起来相当复杂,对于日常正则表达式的使用并不是非常有用。因此,编译的regex模式上的相等性只是引用相等性:

    val x = "abc".r
    val y = "abc".r
    x == y
    // res0: Boolean = false
    
        2
  •  5
  •   stefanobaghino    7 年前

    方法 shouldBe 在Scalatest 3.0.5中,将相等检查委托给 areEqualComparingArraysStructurally 方法:

    def shouldBe(right: Any): Assertion = {
      if (!areEqualComparingArraysStructurally(leftSideValue, right)) {
        val (leftee, rightee) = Suite.getObjectsForFailureMessage(leftSideValue, right)
        val localPrettifier = prettifier // Grabbing a local copy so we don't attempt to serialize AnyShouldWrapper (since first param to indicateFailure is a by-name)
        indicateFailure(FailureMessages.wasNotEqualTo(localPrettifier, leftee, rightee), None, pos)
      }
      else indicateSuccess(FailureMessages.wasEqualTo(prettifier, leftSideValue, right))
    }
    

    然后简单地将相等检查委托给 == 操作员:

    private[scalatest] def areEqualComparingArraysStructurally(left: Any, right: Any): Boolean = {
      // Prior to 2.0 this only called .deep if both sides were arrays. Loosened it
      // when nearing 2.0.M6 to call .deep if either left or right side is an array.
      // TODO: this is the same algo as in scalactic.DefaultEquality. Put that one in
      // a singleton and use it in both places.
      left match {
        case leftArray: Array[_] =>
          right match {
            case rightArray: Array[_] => leftArray.deep == rightArray.deep
            case _ => leftArray.deep == right
          }
        case _ => {
          right match {
            case rightArray: Array[_] => left == rightArray.deep
            case _ => left == right
          }
        }
      }
    }
    

    在Scala中,至少在JVM上, == 只是打电话 equals ,如果不重写,则检查比较的变量是否指向同一对象。 case class es的特殊之处在于编译器重写 等于 以便比较构造函数参数。

    您可以很容易地用以下方法测试它(但正如您所想象的,这同样适用于简单地使用 == 一个人):

    package org.example
    
    import org.scalatest.{FlatSpec, Matchers}
    
    final class MyClass(val a: Int)
    
    final case class MyCaseClass(a: Int)
    
    final class TestSpec extends FlatSpec with Matchers {
    
      "equality on case classes" should "succeed" in {
    
        new MyCaseClass(1) shouldBe new MyCaseClass(1)
    
      }
    
      "equality on non-case classes" should "fail" in {
    
        new MyClass(1) shouldNot be(new MyClass(1))
    
      }
    
      "equality between Regex objects" should "fail" in {
    
        "abc".r shouldNot be("abc".r)
    
      }
    
    }
    

    什么 r 方法正在实例化一个新的 Regex 对象,它不是 案例类 并且不重写相等定义,从而产生您看到的结果。

        3
  •  0
  •   Arcot Deepika    6 年前

    是的,他们不平等。两者 "abc".r 是对两个不同内存位置的不同引用。 应该是 是为了检查 equality 但不是 identity .

    推荐文章