如果你願意訴諸反射,你可以使用標稱和結構類型的混合物:
import scala.language.reflectiveCalls
// A structural type exploiting the fact that all tuples have a _1 field
type IntComponent = { val _1: Int }
def add(list: List[Product with IntComponent], item: Product with IntComponent): List[Product with IntComponent] = {
if(list.isEmpty || list.head._1 > item._1) item :: list
else add(list.tail, item)
}
組合Product with IntComponent
並非絕對必要,IntComponent
就足夠了。但是,這種組合使您的安全性更高一些,並且允許您使用Product
聲明的字段和方法(如果需要)。
這給了你不少的靜態類型安全的:
add(Nil, (1, "foo", null)) // ok
add(Nil, ("foo", 0)) // error
// error: type mismatch;
// found : String("foo")
// required: Int
add(List[Product with IntComponent](Tuple1(1), Tuple2(-1, true)), (0, "yes"))
// Explicit type annotation required, error otherwise
// found : List[Product with Serializable]
// required: List[Product with this.IntComponent]
這種方法的明顯缺點是,你可以在一個Product with IntComponent
任何對象潛行,例如
case class FakeTupleA(_1: Int)
add(Nil, FakeTupleA(99)) // ok
如果沒有Product
要求,以下內容也可以使用:
add(Nil, new FakeTupleB(99))
// error: type mismatch;
// found : this.FakeTupleB
// required: Product with this.IntComponent
你不能讓類型更具體?所有長度相同的元組,可能是'(Int,Any,Any,...)'? – ziggystar 2013-03-06 14:30:41
這就是HList比元組更容易處理的問題。我建議尋找使用,而不是。 – 2013-03-07 10:17:58