如何在scala3中键入任何长度但只有选项的元组



我怎么能有这样的东西

var tuple : (Option[Any]) | (Option[Any], Option[Any]) | (Option[Any], Option[Any], Option[Any]) | (Option[Any], Option[Any], Option[Any], Option[Any])  

但更优雅?

您可以在scala3.0:中执行类似操作

scala> type OptTuple[T <: Tuple] = T match
|   case Option[_] *: t => OptTuple[t]
|   case EmptyTuple => DummyImplicit
|
scala> case class MyTuple[T <: Tuple : OptTuple](tuple: T)
// defined case class MyTuple
scala> val t1 = MyTuple((Option(1), Option("a"), Option(3.0)))
val t1: MyTuple[(Option[Int], Option[String], Option[Double])] = MyTuple((Some(1),Some(a),Some(3.0)))
scala> val t2 = MyTuple((Option(1), Option("a"), 3.0))
-- Error: ----------------------------------------------------------------------
1 |val t2 = MyTuple((Option(1), Option("a"), 3.0))
|                ^
|     Match type reduction failed since selector  Double *: EmptyTuple.type
|     matches none of the cases
|
|         case Option[_] *: t => OptTuple[t]
|         case EmptyTuple => DummyImplicit
1 error found

Scala 3联合是华丽而有趣的,但对于稍微传统一点的方法,尤其是当你最终得到一个需要水平滚动条的类型签名时,还有一些话要说。

在这种情况下,由于您的优先级似乎是单个元组元素的类型安全性,因此我可能建议为儿童使用sealed traitcase classes。

sealed trait MySpecialTuple
case class MyOneTuple(
val field: Option[Any],
) extends MySpecialTuple
case class MyTwoTuple(
val leftHandSide: Option[Int],
val rightHandSide: Option[String],
) extends MySpecialTuple
...
var tuple: MySpecialTuple

由于它是sealed,所以您可以对它进行详尽的模式匹配,以找出里面的内容。如果你想添加额外的功能(比如获取事物或其他属性的"长度"的方法(,这可以是MySpecialTuple上的一个方法。这里的重点是减轻";这个东西可以是十种不同形状中的一种;转移到一堆命名的、文档充分的类中,而不是将其隐藏在一行变量声明中。

最新更新