通过匿名子类将成员添加到内存的Sane方法

时间:2019-01-31 11:31:31

标签: scala

我正在学习Scala和名为Chisel的DSL。 凿子中有一种无所不在的模式,例如:

class TestModule extends Module {
  // overriding an io field of Module
  val io = IO(new Bundle {
    // add a new field, that was not defined in Bundle
    val a = ...
  })
  // do something with io.a
}

正如我发现的那样,从Scala 2.12.0开始就无法编译此代码。由于类型推断为change,因此io字段不会获得'extended'类型,并且io.a在匿名子类定义之外的任何地方都无法有效访问。 我可以(或多或少)了解这种变化的动机。 但这对我来说似乎很奇怪。

我设法写出了一些方法来解决这个问题,但是没有一个方法能完全满足我的要求。

所以: 用新字段扩展覆盖字段对象的最短方法是什么?

  • 从DSL用户的角度来看
  • 从DSL(库)编写器的角度来看

更笼统:“就地”添加字段的最佳方法是什么?而且,如果没有好的方法,为什么就地添加字段呢?

我为DSL用户提供的解决方案:

  • 添加一个明确的类型定义,如更改的作者所假定的
class TestModule extends Module {
  val io: {val a: Type; ...} = IO(new Bundle {
    val a = ...
    ...
  })
}

有点儿打字。再加上三个以上的字段,这看起来真的很吓人。甚至被分成多行。而且在Chisel中,这里通常有很多字段。

  • 首先将整个内容分配到另一个(非覆盖)字段
class TestModule extends Module {
  val myIo = IO(new Bundle {
    val a = ...
    ...
  })
  val io = myIo
}

添加了一个不必要的行,强制发明另一个名称...看起来像魔术。真的。

  • 使类命名而不是匿名
class TestModule extends Module {
  class MyIo extends Bundle {
    val a = ...
    ...
  }
  val io = IO(new MyIo)
}

仍然有一行和一个名字。对于那些来来却没有太多意愿深入使用Scala的人们来说,这看起来有点太复杂了(我不是其中之一,但是我认识很多这样的人)。

对于DSL编写器,我只能建议写一个宏。而且,据我了解的问题,该宏不仅应插入IO()函数的位置,还应替换整个val io = IO(...)分配。

0 个答案:

没有答案