【问题标题】:Scala: Convert heterogeneous Tuple to ListScala:将异构元组转换为列表
【发布时间】:2018-08-03 20:52:43
【问题描述】:

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

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

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

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

似乎必然会丢失类型信息。我们可以做些什么来在这个过程中保留一些类型信息?

【问题讨论】:

  • List((1,2),(1,'a')) 也会丢失类型信息。

标签: scala types type-inference


【解决方案1】:

这是@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))

它显然不能保存所有类型信息,但它至少尝试尽可能多地挽救。

【讨论】:

  • 为什么不简单地def tupToList[T](p: (T, T)): List[T] = List(p._1, p._2)?编译器可以通过更简单的方法签名自动为您的测试用例确定最小上限。
  • @BenReich 确实!谢谢你指出这一点。您介意将您的评论转换为答案吗?然后我可以在这里删除次优解决方案。否则,如果您认为这件事太琐碎,我可以将您的评论复制粘贴到我的答案中,并将其声明为社区 wiki...
猜你喜欢
  • 2015-02-13
  • 2013-01-21
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 2016-09-28
  • 1970-01-01
相关资源
最近更新 更多