如何在scala中默认为不可变的Seq?

时间:2018-03-27 16:36:17

标签: scala functional-programming sequence immutability seq

我今天了解到scala的Seq可能意味着可变或不可变的Seq都可以实现其类型别名。 (我偶然发现blogpost谈论它。)

在我的代码库中,我尝试遵循函数式编程最佳实践,虽然我确实假设scala.collection.immutable.Seq强制执行不可变序列,但它可能不会因此导致意外副作用的入口点。

为了防止可变的Seq,我可以使用序列来输入我的函数:

我的每个文件中的{p> Seq我期待immutable.Seq

我也不想在我的代码库中阅读Seq

对我来说,Set应该像Seq别名一样,默认情况下是不可变的。

有没有办法让默认的super别名指向我的项目的不可变对应项,而不会妨碍供应商的进口?

2 个答案:

答案 0 :(得分:2)

我不建议尝试使用默认的Scala行为。除非你定义自己的函数,它接受任何输入并返回该输入的不可变Seq,我认为使用immutable.Seq

是最安全的

您可以尝试这样的事情(未经过全面测试):

def seq(inputs: Any*): scala.collection.immutable.Seq[Any] = {
  scala.collection.immutable.Seq(inputs)
}
scala> seq("hi", true)
res0: scala.collection.immutable.Seq[Any] = List(WrappedArray(hi, true))

scala> seq(1, 'c', "string", false)
res1: scala.collection.immutable.Seq[Any] = List(WrappedArray(1, c, string, false))

修改

正如jwvh所指出的,这个选项并不理想。如果你坚持自己的功能,那么使用像James Whiteley这样的通用类型可能会更好:

def seq[T](inputs: T*): scala.collection.immutable.Seq[T] =
  scala.collection.immutable.Seq(inputs).flatten

输出:

scala> seq("hi", true)
res0: scala.collection.immutable.Seq[Any] = List(hi, true)

但我会重申 - 最好在需要时使用immutable.Seq,或者找到另一种要使用的集合类型。

答案 1 :(得分:2)

好的,看过(4岁)博客文章后,我真的不认为这是一个很大的问题。

默认Seq()collection.Seq,它本身并不可变,但它是可变和不可变变体的父级。因此,创建并传递默认Seq个集合的代码不受影响,但接受Seq参数的代码可能会收到mutable.Seq。但这只是一个问题,如果不仅仅假设不可变性,而且需要它,例如,用于线程安全。

底线:将import collection.immutable.Seq放在这些文件的顶部:

  1. 您无法控制的客户端代码可能会向您发送可变Seq
  2. 收到的收藏品的不变性至关重要。