加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

模块化Scala设计:如何避免构造函数“推出”样板?

发布时间:2020-12-16 09:12:18 所属栏目:安全 来源:网络整理
导读:也许 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 +
也许 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,s) {

  override def toString = "Bar(%d,s)

}

就这样,当我添加两个酒吧时,我只得到一个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)

如何让两个Bars加入到一起来形成另一个Bar(而不是Foo),以优雅的方式,而不必复制和粘贴Foo的添加方法,如下所示?

class Bar(i: Int,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,s)

}

我有很多这样的酒吧(基本上都是Foo的副本,但是对于类型检查非常重要),一个无需粘贴的解决方案将会产生分红.

谢谢!

解决方法

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

Class Bar与Foo完全相同的构造函数,都是无状态的.如果你想要有几个子类型,只是传达任何其他信息,你可以使用通用参数作为“标签”.例如:

trait Kind
trait Bar extends Kind

class Foo[T<:Kind](val i: Int,val s: String) {
   def add(f: Foo[T]) = new Foo[T](i + f.i,s + f.s)
   override def toString = "Foo(%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)

现在添加是类型安全.然后,您可以使用类型类来获取toString来显示种类.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读