提问人:fluency03 提问时间:8/10/2018 最后编辑:Yuval Itzchakovfluency03 更新时间:10/10/2018 访问量:1313
正则表达式模式相等
Regex pattern equality
问:
在 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
答:
10赞
Andrey Tyukin
8/10/2018
#1
虽然可以决定两个正则表达式是否接受同一种语言,但它似乎相当复杂,对于日常正则表达式的使用并不是那么有用。因此,编译后的正则表达式模式的相等只是引用相等:
val x = "abc".r
val y = "abc".r
x == y
// res0: Boolean = false
评论
0赞
fluency03
8/13/2018
那么在scalatest中,我们没有办法测试两个正则表达式的值是否相等?
0赞
fluency03
8/13/2018
我们可以这样做吗:"abc".r.toString() shouldBe "abc".r.toString()
0赞
fluency03
8/13/2018
然而,“在 Scala 中,至少在 JVM 上,== 只是调用 equals”,这实际上不是引用相等。
2赞
Andrey Tyukin
8/13/2018
@fluency03 与其调用 ,不如问是否 ,因为已经包含生成编译模式的字符串表示形式。这将是一种“廉价”的内涵相等,在某种程度上近似于“有趣的”外延相等。对于 ,只需重定向到 ,即参照相等。toString()
x.regex == y.regex
.regex
regex
equals
eq
-1赞
Balaji Reddy
8/10/2018
#2
是的,它们不相等。两者都是对两个不同内存位置的不同引用。shouldbe是检查平等
而不是身份
。"abc".r
评论
1赞
Dima
8/10/2018
事实并非如此。例如,也是两个不同的参考,但确实如此......val (a,b)=(Some(1), Some(1))
a == b
0赞
Balaji Reddy
8/10/2018
“abc”.r == “abc”.r ...它将返回 false。
0赞
Dima
8/10/2018
完全。在这两种情况下,它们都是不同的内存位置,但在一种情况下结果为 true,但在另一种情况下结果为 false。
5赞
stefanobaghino
8/10/2018
#3
Scalatest 3.0.5 中的方法将相等性检查委托给该方法:shouldBe
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 上,只需调用 ,如果不被覆盖,则检查比较的变量是否指向同一对象。es 的特殊之处在于编译器会覆盖您来比较构造函数参数。==
equals
case class
equals
您可以通过以下方法非常轻松地对其进行测试(但您可以想象,这同样适用于您自己使用):==
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
case class
评论
1赞
stefanobaghino
8/10/2018
这就是我想说的,但我可以看到我的解释很荒谬,我会解决的,谢谢。
0赞
Andrey Tyukin
8/10/2018
也许“字面上是同一块内存”或类似的东西?“字面上相同”在某种程度上仍然模棱两可,因为它通过同样未定义的“相同性”概念定义了尚未定义的“平等”概念。此外,“字面上”这个词可能会给人一种印象,即它更多的是关于描述对象的代码的语法形状,而不是关于它的内存位置。这就是为什么我喜欢“参照平等”这个词——至少,它或多或少是普遍可以理解的。我在吹毛求疵,我知道。;)
1赞
stefanobaghino
8/10/2018
the compared variables point to the same object
应该这样做,希望如此。
0赞
fluency03
8/13/2018
那么在scalatest中,我们没有办法测试两个正则表达式的值是否相等?
0赞
Michael Mior
2/16/2022
@fluency03 只需将正则表达式转换回字符串即可。请注意,两个正则表达式可能表示相同的模式,但它们的字符串表示形式可能不相等。
评论
"abc".r == "abc".r
在 REPL 中也是 false,因此它不是特定于 scalatest 的