【问题标题】:How is this a type mismatch?这是如何类型不匹配的?
【发布时间】:2011-04-08 18:58:42
【问题描述】:
  val eventListeners = new HashMap[Class[Event], ArrayBuffer[Event => Unit]]

  def addEventListener[A <: Event](f: A => Unit)(implicit mf: ClassManifest[A]): A => Unit = {
    eventListeners.getOrElseUpdate(mf.erasure.asInstanceOf[Class[Event]], ArrayBuffer[Event => Unit]()) += f
    f
  }

正在投掷:

error: type mismatch;
 found   : (A) => Unit
 required: (this.Event) => Unit
    eventListeners.getOrElseUpdate(mf.erasure.asInstanceOf[Class[Event]], ArrayBuffer[Event => Unit]()) += f

为什么说它找到了(A) =&gt; Unitf 的值是 (Event) =&gt; Unit 的函数。 A 不只是类型参数,不是签名吗?

调用示例: addEventListener { e:FooEvent =&gt; .... }

【问题讨论】:

    标签: scala types


    【解决方案1】:

    Function1 类的参数是逆变的。即它的类型是Function1[-T, +R]

    这意味着Any =&gt; Unit 的函数是Event =&gt; Unit 的子类型,但对于A 的子类型EventA =&gt; UnitEvent =&gt; Unit 的_super_type。

    所以,问题。如果将类型参数更改为A &gt;: Event,它应该可以工作。

    【讨论】:

      【解决方案2】:

      你向你的ArrayBuffer 承诺你会给它一个函数,它可以接受任何Event 并将其转换为Unit(可能会在此过程中做一些有趣的事情)。

      但是你给它的函数只能取As,它可能不包含所有Events。这显然不是你所承诺的,所以编译器会抱怨。

      您需要弄清楚在这种情况下应该发生什么,并相应地编写代码。例如,您可以创建一个新函数g,如果它收到一个Event,根据您的类清单,它不是A,否则将应用f。或者,您可以要求所有侦听器接受各种事件,并自行负责丢弃他们不想打扰的事件。


      编辑:举个例子让事情更清楚,

      abstract class Fruit { def tasty: String }
      
      class Banana extends Fruit { def tasty = "Yum!" }
      
      abstract class SeededFruit extends Fruit {
        def seedCount: Int
        def tasty = "Mmm, mmm."
      }
      
      class Peach extends SeededFruit { def seedCount = 1 }
      class Apple extends SeededFruit { def seedCount = 5 }
      
      val tellAboutSeeds = (sf: SeededFruit) => println("There are "+sf.seedCount+"seeds")
      
      val fruitTeller = new collection.mutable.ArrayBuffer[Fruit=>Unit]
      fruitTeller += tellAboutSeeds  // If this worked...
      fruitTeller(0)(new Banana)     // ...we'd be in trouble!
      

      【讨论】:

      • A &lt;: Event 不是这样A 确实 包含所有Events 吗?
      • @ryeguy A &lt;: Event 表示AEvent 的特化/子类型。
      • @ziggystar:对,如果AEvent 的子类型,为什么A =&gt; UnitEvent =&gt; Unit 的意思不一样?
      • @ryeguy 仅仅因为你会驾驶汽车并不意味着你可以驾驶任何车辆(甚至是任何东西 , 因为 car 也是 anything 的特化)。
      • @ziggystar 聪明的例子。我喜欢!
      猜你喜欢
      • 2012-12-02
      • 2017-01-02
      • 1970-01-01
      • 1970-01-01
      • 2015-10-01
      • 2011-01-14
      • 1970-01-01
      • 2021-09-15
      • 1970-01-01
      相关资源
      最近更新 更多