【问题标题】:Scala inner class generic boundsScala 内部类泛型边界
【发布时间】:2019-08-05 09:13:59
【问题描述】:

我有类似这样的外部 API 设置:

abstract class PE {
  type Event

  abstract class C[R] {
    def reply(r: R)
    def persist[B <: Event](e: B)(callback: B => Unit): Persist
    def fail(error: Throwable): Persist
  }
  abstract class Persist {
    // ...
  }
}

我想基于 scala 的 Try 类创建一个更像函数的包装器。我想出了以下代码:

def tryPersist[P <: PE, E <: P#Event, R](c: PE#C[R], tryEvent: Try[E])(replyProducer: E => R): PE#Persist = {
    tryEvent match {
        case Success(event) =>
            c.persist(event)(_ => c.reply(replyProducer(event)))
        case Failure(exception) =>
            c.fail(exception)
    }
  }

但是,这不起作用,因为 scala 拒绝接受 PE#Persist 作为 PE.this.Persist。有什么遗漏吗?

inferred type arguments [E] do not conform to method persist's type parameter bounds [B &lt;: _1.Event] c.persist(event)(_ =&gt; c.reply(replyProducer(event)))

在通话地点:

[error]  found   : MyPEImpl#Persist
[error]  required: MyPEImpl.this.Persist
[error]                     persistEvent(ctx, command.eventFor(state))(_.playerBet)

PS:如果有人注意到,是的,它是 Lagom PersistentEntity 的 API

【问题讨论】:

    标签: scala generics inner-classes


    【解决方案1】:

    这失败了,因为PE.this.Persist 是PE#Persist 的子类型,所以您尝试传递需要特定子类型的超类型。

    当类型像这样嵌套时,Scala 会为封闭类的每个实例创建一个新的嵌套类型。因此,使用PE 的一个实例创建的Persist 实例与使用PE 的不同实例创建的Persist 实例不兼容。符号PE#Persist 表示所有不同PE.this.Persist 类型的超类型。

    【讨论】:

    • 那么,如何指定PE#Persist 的实际子类型?我需要以某种方式传递pe: PE, c: pe.CommandContext[R] 吗?
    • 您可以将persist 更改为def persist[B &lt;: PE#Event],但显然这会影响persist 的功能。
    • 那是外部 API,我无法更改它@Tim
    猜你喜欢
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 2019-09-05
    • 2021-01-24
    • 2020-07-22
    • 2013-05-31
    相关资源
    最近更新 更多