我有一种方法可以将不同类型的元组添加到列表中,第一个元组元素始终是Int。我需要做一个“大于”比较但是在Any类型上不允许这样做。有人能告诉我如何在下面达到预期的效果吗?
由于 Des
private def add(list: List[Product], item: Product): List[Product] = {
if(list.isEmpty || list.head.productElement(0) > item.productElement(0)) item :: list
else add(list.tail, item)
}
答案 0 :(得分:1)
如果由于Producer
具有变量arity而无法接受ziggystar的建议,则可以通过重构避免复杂且可能不太可读的方法来实现预期效果。例如:
case class Item(i: Int, item: Product)
def add(list: List[Item], item: Item): List[Item] = {
if (list.isEmpty || list.head.i > item.i) item :: list
else add(list.tail, item)
}
,使用时,如下所示:
add(Nil, Item(1, (1, "b"))) // List(Item(1,(1,b)))
add(List(Item(1, (1, "a"))), Item(2, (1, "b"))) // List(Item(2,(1,b)))
add(List(Item(2, (1, "a"))), Item(1, (1, "b"))) // List(Item(1,(1,b)), Item(2,(1,a))
答案 1 :(得分:0)
如果你愿意采用反思,你可以使用名义和结构类型的混合:
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