案例类Person(firstName:String,lastName:String)
vs
输入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)}
上面的示例需要对集合进行额外的迭代,以及额外的对象创建。 可以使用视图
users.zip(scores).view.map{(id ,score) => UserScores(id,score)}.force
但我不太确定它会产生预期效果
答案 0 :(得分:9)
当它是最合适的抽象级别时,你应该使用元组。
例如,如果你正在编写一个框架,其中一切都是完全通用的,你可以得到的最具体的东西是“函数”,“笛卡尔积”,“半群”或类似“封闭的幺半群类”,那么你可能别无选择,只能使用Tuple
。这是一个很好的例子:Semigroupal方法:
product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
这里,元组类型的使用是完全合理的,因为接口足够抽象。
另一个例子:在整个Scala collection library中,你永远不会遇到像Person(name: String, surname: String)
这样具体的东西,但是你会看到很多方法都在泛型类型的元组上工作{{1} }。
但是,如果代码中最抽象的东西是
(A, B)
然后你突然发现你还需要object Fred {
val name = "Fred"
val surname = "Bloggs"
}
的另一个类似对象,定义
John Doe
然后甚至可能像这样使用它:
case class Person(name: String, surname: String)
当然,准确建模域名具有重要价值。这两个目标 - 准确地建模具体领域与编写在尽可能多的情况下工作的通用框架 - 是互补的。
总结:
这里:
val j = Person(name = "John", surname = "Doe")
看起来像域和使用的抽象之间的不匹配。您可以简单地从编译器不会阻止您意外地交换这两个组件的事实看到它。相反,如果您使用通用type Person = (String, String) //firstName, lastName
和A
类型在不同的抽象级别工作,如果您不小心交换了B
(B, A)
,编译器会发出错误消息预期
答案 1 :(得分:4)
恕我直言,作为一般规则:
可是:
关于类型别名的最后一条评论:当我不想创建类时,我主要使用它们来提高可读性。这种情况发生在两种情况下:
param: Map[String, Double]
。 Map是一个很好的类型,你不想把它包装在一个类中。然后,可能更具可读性,在您的代码ApiParams
type ApiParams = Map[String, Double]
答案 2 :(得分:1)
也许如果订单无关紧要。因此,与firstName / lastName示例不同,它有区别。
仍然没有可用的信息,值是什么,但在一般情况下,可能没有信息。