什么时候使用元组而不是案例类是有意义的

Eug*_*eMi 8 scala

case类Person(firstName:String,lastName:String)

VS

type Person =(String,String)// firstName,lastName

案例类显然更具可读性.但是,我看到人们使用后者.什么时候使用元组代替它?

作为后续行动

有性能差异吗?在一些使用Tuple2的语言中,就像使用两个原语一样,而创建一个类则会产生开销.但是Scala看起来像Tuple被实现为类.如果我想要压缩两个sequances的情况怎么样,但更喜欢输出是一个案例类,因为下面提到的所有原因.

例如

`case class UserScores(userId: Long, score: Double)`
users.zip(scores).map{(id ,score) => UserScores(id,score)}
Run Code Online (Sandbox Code Playgroud)

上面的示例需要对集合进行额外的迭代,以及额外的对象创建.可以使用视图代替

users.zip(scores).view.map{(id ,score) => UserScores(id,score)}.force
Run Code Online (Sandbox Code Playgroud)

但我不太确定它会产生预期的效果

And*_*kin 9

当它是最合适的抽象级别时,您应该使用元组.

例如,如果你正在编写一个框架,其中一切都是完全通用的,你可以得到的最具体的东西是"函数","笛卡尔积","半群"或类似"封闭的幺半群类",那么你可能除了使用之外别无选择Tuple.这是一个很好的例子:Semigroupal with method:

 product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
Run Code Online (Sandbox Code Playgroud)

这里,元组类型的使用是完全合理的,因为接口足够抽象.

另一个例子:在整个Scala集合库中,你永远不会遇到任何具体的东西Person(name: String, surname: String),但是你会看到很多方法都适用于泛型类型的元组(A, B).

但是,如果代码中最抽象的东西是

object Fred {
  val name = "Fred"
  val surname =  "Bloggs"
}
Run Code Online (Sandbox Code Playgroud)

然后你突然发现你还需要另一个类似的对象John Doe,定义它会更合适

case class Person(name: String, surname: String)
Run Code Online (Sandbox Code Playgroud)

然后甚至可能像这样使用它:

val j = Person(name = "John", surname = "Doe")
Run Code Online (Sandbox Code Playgroud)

当然,准确建模域名具有重要价值.这两个目标 - 准确地建模具体领域与编写在尽可能多的情况下工作的通用框架 - 是互补的.

总结一下:

  • 你在编写一个足够抽象的完全通用的框架吗?使用元组.
  • 您是否尝试尽可能地模拟某些具体领域?使用适当命名的案例类.

这里:

type Person = (String, String) //firstName, lastName
Run Code Online (Sandbox Code Playgroud)

看起来像域和使用的抽象之间的不匹配.您可以简单地从编译器不会阻止您意外地交换这两个组件的事实看到它.相反,如果您使用泛型AB类型在不同的抽象级别工作,如果您意外地交换(B, A)(A, B)预期的位置,编译器将发出错误消息.


use*_*own 1

如果顺序不重要的话也许可以。与您的名字/姓氏示例不同,那里有区别。

仍然没有可用的信息,即值是什么,但在一般情况下,可能没有信息。