Scala:将异构元组转换为List

时间:2018-02-23 18:14:23

标签: scala types type-inference

在Scala命令行上,写入没有问题:

List((1,2),(1,'a'))

但我似乎无法编写将Tuple2转换为List的函数,因为Tuple2需要2个类型参数,但List只有一个。{1}}。任何尝试,例如:

def tuple2ToList[T1, T2](pair: (T1, T2)): List[Any] = List(pair._1, pair._2)

似乎必然会丢失类型信息。我们可以做些什么来保留过程中的某些类型信息吗?

1 个答案:

答案 0 :(得分:2)

这是@BenReich在评论中提出的解决方案

只需使用一个类型参数而不是两个,编译器就会 自动选择两者类型的最小上限 元组元素:

def tupleToList[T](p: (T, T)): List[T] = List(p._1, p._2)

示例:

scala> tupleToList((Some(42), None))
res4: List[Option[Int]] = List(Some(42), None)

scala> tupleToList((0.9999, 1))
res5: List[AnyVal] = List(0.9999, 1)

scala> tupleToList((Set(1), List(1)))
res6: List[scala.collection.immutable.Iterable[Int] with Int => AnyVal] = List(Set(1), List(1))

这是旧的次优解决方案,我将其作为@ BenReich评论的背景留在这里。

将返回类型定义为T1T2的最小上限:

def tupleToListRescueTypeInfo[R, T1 <: R, T2 <: R](p: (T1, T2)): List[R] = 
  List(p._1, p._2)

小测试:

scala> tupleToListRescueTypeInfo((2, 3))
res0: List[Int] = List(2, 3)

scala> tupleToListRescueTypeInfo((Some[Int](3), None))
res1: List[Option[Int]] = List(Some(3), None)

scala> tupleToListRescueTypeInfo((List(1,2), Set(1,2)))
res2: List[scala.collection.immutable.Iterable[Int] with Int => AnyVal] = 
  List(List(1, 2), Set(1, 2))

显然无法保留所有类型的信息,但它至少会尝试尽可能地进行救援。