【问题标题】:Abstracting implicit val of case class抽象案例类的隐式val
【发布时间】:2013-05-31 23:52:17
【问题描述】:

当我在 Scala 中使用案例类编写程序时,我遇到了一个反复出现的模式,我希望将案例类的创建者作为参数提供给它以供将来参考。我了解到我们可以通过将隐式值赋予案例类来捕捉这种模式

abstract class MessageCreator
case class SomeMessage(s:String)(implicit val creator:MessageCreator)
class MyCreator extends MessageCreator { implicit val creator = this}
class ACreator extends MyCreator { def newMessage = SomeMessage("hello") }

然后,这里的 newMessage 将有成员 creator 引用 ACreator 本身的实例。

现在,我有一堆可以做同样事情的案例类。我的问题是,你如何重复这种模式而不必每次我想定义这样的案例类时复制和粘贴(implicit val creator:MessageCreator)

我尝试用隐式 val 定义一个抽象类,然后从案例类继承它们,但 Scala 抱怨抽象类的隐式 val 没有在案例类中定义。显然,case 类不能被继承。

如果这不能以编程方式完成,我可能会开始考虑编写一个宏(这将是一个很好的解决方案)。我想确保这里没有遗漏任何东西。

【问题讨论】:

  • 恕我直言,此类参数应显式且仅显式传递。如果你真的需要这个,你可以使用伴随对象作为工厂来传递创建者参数。
  • 感谢您的评论。如果我有一个伴生对象,比如def apply(implicit val creator:MessageCreator) {...},我如何让案例类继承这样的伴生对象类?

标签: scala


【解决方案1】:

在不了解该领域的情况下,我会问一些类似以下问题的问题:

  1. 为什么你的工厂不能成为你的伴侣对象?对于案例类,由于语言及其编译器,这已经是明确的。如果你需要另一个我会超载申请。

  2. 为什么你的班级需要创造更多自己的能力?这不是“复制”的部分内容吗(我的意思是部分没有替换所有字段。)

我要问这些问题的季节是,在没有上下文的情况下,听起来你引入了额外的复杂性而没有太多好处。

最后,如果您隐式传递状态,我会提醒您不要这样做。这可能会导致各种问题和问题。除非它们引起错误,否则隐式非常棒,在这种情况下,该错误变得难以破译和追踪。我几乎可以说你应该只对类型类使用隐式

【讨论】:

  • 嗨,谢谢你的回答 1。当然,我可以用伴随对象实现类似的事情。但它赋予了什么价值?而且它似乎并没有提供我想要的继承权(或者是这样吗?)
  • 2.好吧,让我从第一个原则开始论证。如果程序员一遍又一遍地为同一个问题重复编写相同的代码块,他/她很自然会想到抽象它的方法,这样他/她就不需要给隐含'这样的东西命名创造者的价值,并依赖命名约定来满足不同实体的共同关注。现在,如果 Scala 是同音语言,实现起来将是一件很自然的事情。随着最近向 Scala 添加宏,我可以使用宏来做到这一点。问题是,它可以在 Scala 的语义范围内完成吗?
  • 还有 w.r.t.您的最后一条评论,我隐含地传递了对一个类的引用。我没有在 OP 中提到,但问题的上下文是我想在演员互相发送消息时传递消息的发件人,这样我就可以追踪演员的原始发件人。对我来说,这听起来不像是绕过状态。但是,当然,人们可以滥用这一点并继续对原始发件人产生副作用,这是不可取的。
猜你喜欢
  • 2021-11-14
  • 2012-01-02
  • 2016-01-23
  • 1970-01-01
  • 2014-06-21
  • 2014-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多