我今天了解到scala的Seq
可能意味着可变或不可变的Seq都可以实现其类型别名。 (我偶然发现blogpost谈论它。)
在我的代码库中,我尝试遵循函数式编程最佳实践,虽然我确实假设scala.collection.immutable.Seq
强制执行不可变序列,但它可能不会因此导致意外副作用的入口点。
为了防止可变的Seq,我可以使用序列来输入我的函数:
我的每个文件中的{p>Seq
我期待immutable.Seq
。
我也不想在我的代码库中阅读Seq
。
对我来说,Set
应该像Seq
别名一样,默认情况下是不可变的。
有没有办法让默认的super
别名指向我的项目的不可变对应项,而不会妨碍供应商的进口?
答案 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
放在这些文件的顶部:
Seq
和