我怎么能有这样的东西
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 trait
和case class
es。
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
上的一个方法。这里的重点是减轻";这个东西可以是十种不同形状中的一种;转移到一堆命名的、文档充分的类中,而不是将其隐藏在一行变量声明中。