【问题标题】:scala type mismatch. found type, required _$1scala 类型不匹配。找到类型,需要 _$1
【发布时间】:2014-09-26 09:11:55
【问题描述】:

我遇到了一个我不理解的编译器错误。下面的代码会产生以下错误:

错误:类型不匹配; 找到:oldEntity.type(基础类型为 com.mycompany.address.AddressEntity) 必需:$1 this.esDocsForAddressEntity.filter(.shouldTriggerRefresh(oldEntity, newEntity)).map(_.esDocName)

object AddressToEsDocMapper {


  private val esDocsForAddressEntity = List[EsDocRefreshTrigger[_]](new PartyAddressRefreshTrigger())


  def findEsDocsForUpdate(oldEntity : AddressEntity, newEntity : AddressEntity) : List[String] = {
    this.esDocsForAddressEntity.filter(_.shouldTriggerRefresh(oldEntity, newEntity)).map(_.esDocName)
  }


  private class PartyAddressRefreshTrigger extends EsDocRefreshTrigger[AddressEntity] {

    val esDocName = "PartyAddress"

    override def shouldTriggerRefresh(oldEntity : AddressEntity, newEntity : AddressEntity) : Boolean = {
      oldEntity.addressLine2 != newEntity.addressLine2 || 
      oldEntity.addressLine3 != newEntity.addressLine3 || 
      oldEntity.addressLine1 != newEntity.addressLine1
    }

  }

}

【问题讨论】:

    标签: scala


    【解决方案1】:

    您没有提供所有代码,但可能是因为您在esDocsForAddressEntity 的定义中使用了通配符。在求解表达式中的类型参数时,它无法将 oldEntity 与任意 EsDocRefreshTrigger 的类型 arg 关联起来。

    $1 名称只是编译器的内部或临时名称。

    不是一个很好的例子,但是:

    scala> val ss = List[Option[_]](Some("a"))
    ss: List[Option[_]] = List(Some(a))
    
    scala> ss filter (_.isDefined)
    res2: List[Option[_]] = List(Some(a))
    
    scala> ss filter (_.get.length > 0)
    <console>:9: error: value length is not a member of _$1
                  ss filter (_.get.length > 0)
                                   ^
    

    蛮力:

    scala> class Foo { type A ; def foo(a: A) = 42 }
    defined class Foo
    
    scala> class Bar extends Foo { type A = Int }
    defined class Bar
    
    scala> class Baz extends Foo { type A = String }
    defined class Baz
    
    scala> val foos = List[Foo](new Bar, new Baz)
    foos: List[Foo] = List(Bar@55cb6996, Baz@1807e3f6)
    
    scala> foos map { case bar: Bar => bar foo 3 ; case baz: Baz => baz foo "three" }
    res1: List[Int] = List(42, 42)
    
    scala> def f(x: Foo)(a: x.A) = x foo a
    f: (x: Foo)(a: x.A)Int
    

    或为 Bars 和 Bazes 提供 foo 方法的类型类。

    【讨论】:

    • 嗨 som-snytt。是的,通配符就是问题所在。当我指定 AddressEntity 而不是通配符时,错误消失了。但我真的需要它作为通配符。我希望能够在那里传递任何类型的实体。你知道我可以如何更改此代码以使其正常工作吗?
    • @KevinStembridge 有很多编码方法。对不起,我没有做到公正。模式匹配种类的意思是“任何种类的实体”,但模擦除。可能你真的不想要“任何一种”。
    • 我必须承认,如果我确实想接受任何类型的实体,我仍然不知道该如何编写代码。但你是对的。事实证明,我毕竟不需要通配符,因为这个映射器特定于 AddressEntity。非常感谢您的帮助。
    猜你喜欢
    • 2015-04-03
    • 1970-01-01
    • 2021-09-25
    • 2019-04-30
    • 2019-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多