scala - 模块化Scala设计: how do I avoid a constructor "push-out" boilerplate?

标签 scala boilerplate

也许具有良好风格和优雅意识的 Scala 专家可以帮助我找到一种更好的方法来构造以下代码,该代码存在构造函数“推出”问题。

我们从一个简单的基类开始:

class Foo(val i: Int, val d: Double, val s: String) {

  def add(f: Foo) = new Foo(i + f.i, d + f.d, s + f.s)
  override def toString = "Foo(%d,%f,%s)".format(i,d,s)

}

出于复杂应用程序中的类型检查目的,我需要一个没有任何附加状态的子类:

class Bar(i: Int, d: Double, s: String) extends Foo(i,d,s) {

  override def toString = "Bar(%d,%f,%s)".format(i,d,s)

}

就目前情况而言,当我添加两个 Bar 时,我只返回一个 Foo:

val x = new Bar(1,2.3,"x")
val y = new Bar(4,5.6,"y")
val xy = x.add(y)

在 REPL 中包含以下响应:

x  : Bar = Bar(1,2.300000,x)
y  : Bar = Bar(4,5.600000,y)
xy : Foo = Foo(5,7.900000,xy)

如何以优雅的方式将两个 Bar 添加在一起形成另一个 Bar(而不是 Foo),而不必复制并粘贴 Foo 的 add 方法,如下所示?

class Bar(i: Int, d: Double, s: String) extends Foo(i,d,s) {

  // ugly copy-and-paste from Foo:
  def add(b: Bar) = new Bar(i + b.i, d + b.d, s + b.s)
  override def toString = "Bar(%d,%f,%s)".format(i,d,s)

}

我有很多这样的 Bar(本质上都是 Foo 的副本,但对于类型检查非常重要),免剪切和粘贴的解决方案将带来好处。

谢谢!

最佳答案

我尽量避免继承。所以这是一种替代方法。

BarFoo 具有完全相同的构造函数,并且两者都是无状态的。如果您想要有多个子类型,只是为了传达任何附加信息,您可以使用通用参数作为“标签”。例如:

trait Kind
trait Bar extends Kind

class Foo[T<:Kind](val i: Int, val d: Double, val s: String) {
   def add(f: Foo[T]) = new Foo[T](i + f.i, d + f.d, s + f.s)
   override def toString = "Foo(%d,%f,%s)".format(i,d,s)
}


scala> val b1 = new Foo[Bar](2,3.0,"hello")
b1: Foo[Bar] = Foo(2,3.000000,hello)

scala> val b2 = new Foo[Bar](3,1.0," world")
b2: Foo[Bar] = Foo(3,1.000000, world)

scala> b1 add b2
res1: Foo[Bar] = Foo(5,4.000000,hello world)

现在 add 是类型安全的。然后,您可以使用类型类来获取 toString 以显示 Kind

关于scala - 模块化Scala设计: how do I avoid a constructor "push-out" boilerplate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12259254/

相关文章:

scala - 为什么 scala 无法推断具有多个参数列表的函数的公共(public)返回类型?

scala - 如何初始化具有多个操作的字段?

c++ - 如何在 Unix/Linux 中创建软件包?

HTML5 Boilerplate .htaccess 重写为 index.php

java - 试图让 InetAddress.getLocalHost.getHostAddress (Java/Scala) 返回外部 IP

scala - 如何使 scala 集合包含唯一元素? ("unique"定义)

C# 样板代码

html - 更少的样板文件来启动一个元素

php - PHP中缺少对象属性如何解决?

scala - 在scala中的另一个线程上执行一个简单的任务