为什么将 Scala Set 转换为 Vector 而不是 List?
Why is a scala Set casted to a Vector instead of a List?
我想知道如果我要求 Seq[A]
子类,为什么 Set[A]
会转换为 Vector[A]
?为了说明这一点,请看下面的例子:
val A = Set("one", "two")
val B = Set("one", "two", "three")
def f(one: Seq[String], other : Seq[String]) = {
one.intersect(other) match {
case head :: tail => head
case _ => "unknown"
}
}
f(A.to, B.to)
这个函数将return "unknown" 而不是一个。原因是 A.to
将被转换为 Vector[String]
。 cons 运算符 (::
) 不是为向量定义的,而是为列表定义的,因此应用第二种情况并且 "unknown" 是 returned。要解决此问题,我可以使用为所有 Seqs
定义的 +:
运算符或将集合转换为列表 (A.to[List]
)。所以我的(学术)问题是:
为什么 A.to
return 是向量。至少根据 scala docs,Seq
的默认实现是 LinearSeq
而它的默认实现是 List
。我做错了什么?
因为它可以,所以您依赖于运行时 class 实现细节,而不是编译时类型信息保证。 to
或 toSeq
方法可以自由地 return 任何类型检查,它甚至可以生成一个随机数并在该数字的基础上选择一个具体的 class,所以你可以得到一个 List 其他时间 Vector 或其他什么。它甚至可以根据操作系统来决定。当然,我在这里很迂腐,希望他们不会那样做,但我的意思是,我们无法真正解释,这就是实现的作用,将来可能会改变。
此外,"default implementation of Seq is a List"仅适用于构造函数。而且,他们可能会随时更改它。
所以,如果你想要一个 List 就要求一个 List,而不是 Seq.
我想知道如果我要求 Seq[A]
子类,为什么 Set[A]
会转换为 Vector[A]
?为了说明这一点,请看下面的例子:
val A = Set("one", "two")
val B = Set("one", "two", "three")
def f(one: Seq[String], other : Seq[String]) = {
one.intersect(other) match {
case head :: tail => head
case _ => "unknown"
}
}
f(A.to, B.to)
这个函数将return "unknown" 而不是一个。原因是 A.to
将被转换为 Vector[String]
。 cons 运算符 (::
) 不是为向量定义的,而是为列表定义的,因此应用第二种情况并且 "unknown" 是 returned。要解决此问题,我可以使用为所有 Seqs
定义的 +:
运算符或将集合转换为列表 (A.to[List]
)。所以我的(学术)问题是:
为什么 A.to
return 是向量。至少根据 scala docs,Seq
的默认实现是 LinearSeq
而它的默认实现是 List
。我做错了什么?
因为它可以,所以您依赖于运行时 class 实现细节,而不是编译时类型信息保证。 to
或 toSeq
方法可以自由地 return 任何类型检查,它甚至可以生成一个随机数并在该数字的基础上选择一个具体的 class,所以你可以得到一个 List 其他时间 Vector 或其他什么。它甚至可以根据操作系统来决定。当然,我在这里很迂腐,希望他们不会那样做,但我的意思是,我们无法真正解释,这就是实现的作用,将来可能会改变。
此外,"default implementation of Seq is a List"仅适用于构造函数。而且,他们可能会随时更改它。
所以,如果你想要一个 List 就要求一个 List,而不是 Seq.