scala - 为什么 Scala 中的单元素元组没有 Tuple1 文字?

标签 scala syntax tuples

Python 有 (1,)对于单个元素元组。在 Scala 中,(1,2)适用于 Tuple2(1,2)但我们必须使用 Tuple1(1)获取单个元素元组。这似乎是一个小问题,但设计期望产品的 API 对于传递单个元素的用户来说是一件痛苦的事情,因为他们必须编写 Tuple1(1)。

也许这是一个小问题,但 Scala 的一个主要卖点是打字多,打字少。但在这种情况下,似乎打字更多。

请告诉我:
1)我错过了这个,它以另一种形式存在,或者
2)它将被添加到该语言的 future 版本中(他们将接受补丁)。

最佳答案

您可以定义隐式转换:

implicit def value2tuple[T](x: T): Tuple1[T] = Tuple1(x)

隐式转换仅在参数的静态类型不符合方法参数的类型时才适用。假设您的方法采用 Product争论
def m(v: Product) = // ...

转换将适用于非产品值,但不适用于 Tuple2 , 例如。警告:所有案例类都扩展了 Product trait,因此转换也不适用于它们。相反,产品元素将是案例类的构造函数参数。
ProductTupleX 的最小上限类,但如果要将隐式 Tuple1 转换应用于所有非元组,则可以使用类型类:
// given a Tupleable[T], you can call apply to convert T to a Product
sealed abstract class Tupleable[T] extends (T => Product)
sealed class ValueTupler[T] extends Tupleable[T] { 
   def apply(x: T) = Tuple1(x) 
}
sealed class TupleTupler[T <: Product] extends Tupleable[T] { 
   def apply(x: T) = x 
}

// implicit conversions
trait LowPriorityTuple {
   // this provides a Tupleable[T] for any type T, but is the 
   // lowest priority conversion
   implicit def anyIsTupleable[T]: Tupleable[T] = new ValueTupler
}
object Tupleable extends LowPriorityTuple {
   implicit def tuple2isTuple[T1, T2]: Tupleable[Tuple2[T1,T2]] = new TupleTupler
   implicit def tuple3isTuple[T1, T2, T3]: Tupleable[Tuple3[T1,T2,T3]] = new TupleTupler
   // ... etc ...
}

您可以在 API 中使用此类型类,如下所示:
def m[T: Tupleable](v: T) = { 
   val p = implicitly[Tupleable[T]](v) 
   // ... do something with p
}

如果您的方法返回产品,您可以看到转换是如何应用的:
scala> def m[T: Tupleable](v: T) = implicitly[Tupleable[T]](v)
m: [T](v: T)(implicit evidence$1: Tupleable[T])Product

scala> m("asdf") // as Tuple1
res12: Product = (asdf,)

scala> m(Person("a", "n")) // also as Tuple1, *not* as (String, String)
res13: Product = (Person(a,n),)

scala> m((1,2)) // as Tuple2
res14: Product = (1,2)

关于scala - 为什么 Scala 中的单元素元组没有 Tuple1 文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6460626/

相关文章:

json - Apache Spark 和 MongoDB Hadoop-Connector 创建的 BSON 结构

scala - 从函数参数推断类型参数

scala - 用 Future 满足抽象特征要求

c - C中初始化列表中的这个语法是什么意思?

c++ - 从强类型元组创建 PoD 元组

python - 将元组转换为日期时间

python - 为什么python允许元组作为字典的键

scala - sbt-assembly:如何在 src/main/webapp 中包含静态文件

sql - 无法使用 sqldf 对 R 中的函数使用rank()

python - X 和 Y 或 Z - 三元运算符