您可以指定結果類型:
val rescala> val result: List[Int] = "string" :: l
<console>:8: error: type mismatch;
found : String
required: Int
val result: List[Int] = "string" :: l
^
你也可以創建自己的不變的方法是這樣的:
def prepend[T1, T2](t: T1, l: List[T2])(implicit e: T1 =:= T2) = e(t) :: l
prepend(0, l)
// List[Int] = List(0, 1, 2, 3)
scala> prepend("str", l)
<console>:10: error: Cannot prove that String =:= Int.
prepend("str", l)
^
隨着value classes你可以爲List
創建不變的包裝沒有運行時罰款是這樣的:
case class InvariantList[T](l: List[T]) extends AnyVal {
def ::(t: T) = InvariantList(t :: l)
}
val l = InvariantList(1 :: 2 :: 3 :: Nil)
0 :: l
// InvariantList(List(0, 1, 2, 3))
scala> "str" :: l
<console>:13: error: type mismatch;
found : String
required: Int
"str" :: l
^
你也可以使用從scalaz
不變的方法收集連接:
import scalaz._, Scalaz._
List(0) |+| List(1, 2, 3)
// List(0, 1, 2, 3)
Vector('a) |+| Vector('b, 'c)
// Vector('a, 'b, 'c)
scala> List("string") |+| List(1, 2, 3)
<console>:14: error: type mismatch;
found : Int(1)
required: String
List("string") |+| List(1, 2, 3)
^
注意(由@drexin提到的)有一個不變的列表scalaz:IList。
到處指定結果類型意味着我放棄了類型推斷。包裝/擴展scala.collection._的所有方法將花費大量時間,我需要在我的所有項目中攜帶此代碼... – OlivierBlanvillain
@OlivierBlanvillain:您無需在任何地方指定結果類型。您可以將其指定爲所有方法和所有類成員的結果。所以你會以任何方式得到編譯錯誤。 – senia
我總是設置返回類型,但我仍然設法編寫buggy代碼,因爲意外協變;) – OlivierBlanvillain