==
运算符是否真的按内容比较列表?特别是关于空列表?
以下比较符合预期
List("A", "B", "C") == "ABC".split("").toList // true
List() == List() // true
List.empty[String] == List.empty[String] // true
但是,不同类型的空列表比较会产生令人困惑的结果:
List.empty[String] == List.empty[Int] // true: on different types?
编辑:在第一个问题中,我提出了一个误导性的测试案例,安德烈(Andrey)对此进行了澄清。谢谢。转载在这里
val emptyStrSplit = "".split("").toList // List("") and not List() as displayed in Console
List.empty[String] == emptyStrSplit // false: b/c List() != List("")
答案 0 :(得分:5)
List.empty[String]
是单例对象Nil
,它扩展了List[Nothing]
(协变,List[String]
的子类型)。List.empty[Int]
是单例对象Nil
,它扩展了List[Nothing]
(协变,List[Int]
的子类型)。Nil == Nil
为true。因此,从本质上讲,您有一个对象Nil
,它同时具有List[String]
类型和List[Int]
类型。这就是子类型化的结果。我在这里看不到任何奇怪或矛盾的地方。
如果要确保类型相同,可以使用implicit
类型的A =:= B
证据作为默认值null
,然后检查是否非{{1 }}证据由编译器提供:
null
示例:
def eqSameType[A, B](a: A, b: B)(implicit ev: A =:= B = null) =
if (ev == null) false else a == b
答案 1 :(得分:4)
即使忽略类型擦除问题和“它们实际上是同一对象”问题,equals
上Seq
的文档也指出:
def equals(that: Any): Boolean
用于任意序列的equals方法。
返回:如果该序列具有与该序列相同的元素且顺序相同,则为true,否则为false
使所有空序列相等:它们具有相同元素的顺序相同,即没有。空List
等于空Vector
,Queue
,Stream
等。
答案 2 :(得分:1)
除了Andrey的答案外,即使List.empty[T]
(或List[T]()
)确实返回了List
的新实例,由于类型不同,您仍然应该期望各种类型的空列表相等删除。例如,使用ListBuffer
,其empty
方法每次都会返回新的ListBuffer
:
import scala.collection.mutable.ListBuffer
ListBuffer.empty[Int] == ListBuffer.empty[String]
如果您想要一种方法来检测两个列表何时具有不同的编译时类型,则可以使用TypeTags
:
import scala.reflect.runtime.universe.{ TypeTag, typeTag }
def equalAndSameType[A: TypeTag, B: TypeTag](as: Seq[A], bs: Seq[B]) =
typeTag[A] == typeTag[B] && as == bs
equalAndSameType(List.empty[Int], List.empty[String]) // returns false
不过,我不确定这何时会有用。
答案 3 :(得分:0)
编辑:使用$('.#open_lightbox').on('click', function(ev) {
setTimeout(function() {
$("#video1")[0].src += "&autoplay=1";
},150);
//ev.preventDefault();
});
的此实现还不够好。 Brian使用ClassTag
的答案更好。
尽管从Scala的角度来看,Andrey的回答是完全合理的。我认为让TypeTag
为假而不是真更具商业意义。以下是使用上下文的自定义比较器,该上下文必须支持以下内容。不确定这是否是最优雅的方式。
List.empty[String] == List.empty[Int]