我正在学习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
在匿名子类定义之外的任何地方都无法有效访问。
我可以(或多或少)了解这种变化的动机。
但这对我来说似乎很奇怪。
我设法写出了一些方法来解决这个问题,但是没有一个方法能完全满足我的要求。
所以: 用新字段扩展覆盖字段对象的最短方法是什么?
更笼统:“就地”添加字段的最佳方法是什么?而且,如果没有好的方法,为什么就地添加字段呢?
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(...)
分配。