【问题标题】:Couldn't derive type无法派生类型
【发布时间】:2016-12-05 23:43:39
【问题描述】:

我正在使用 Scala 和 CouchDB,并创建了一个通用的 save 方法来将我的对象存储在数据库中。因为它是通用的,所以无法编译代码。

我的通用 save 方法如下所示:

abstract class AbstractRepository[T] extends LazyLogging {
  private val config = ConfigFactory.load()
  private val hostname: String = config.getString("couchdb.hostname")
  private val port: Int = config.getInt("couchdb.port")

  val couch = CouchDb(hostname, port)
  val mapping: TypeMapping
  val db: CouchDbApi

  def save(item: T): Unit = {
    db.docs.create(item)
  }
}

AbstractRepositorySummonerRepository 扩展:

class SummonerRepository extends AbstractRepository[Summoner] {
  val mapping = TypeMapping(classOf[Summoner] -> "Summoner")
  val db = couch.db("summoner-db", mapping)
}

当我尝试编译这个时,我得到了这个错误:

错误:(24, 34) 无法派生类型 T db.docs.create(item)

我不明白为什么不能推导出来。为什么会这样,有没有办法解决这个错误?

编辑:当我将类型转换为 Summoner 时,它可以完美运行,但这没有用,因为它不再是通用的:

def save(item: T): Unit = {
        db.docs.create(item.asInstanceOf[Summoner])
      }

【问题讨论】:

  • 从纯 Scala 的角度来看,一切都很好(也就是说,有一个带有定义为抽象类类型参数的泛型参数的方法,并用具体的类型值实例化它)。错误信息对我来说似乎不熟悉,所以我用谷歌搜索了一下,什么也没找到;由于文件名冲突或具有> 21个字段的案例类而导致错误的同一消息只是几个不相关的问题。所以我认为这可能是 CouchDB 的事情。 db.docs.create 取什么样的参数?当然,它不能采用在外部范围中定义的一些通用 T 类型。
  • db.docs.create[T](item) 工作吗?
  • @ipoteka 不幸的是没用
  • @slouc def create[D: W](obj: D): Task[Res.DocOk] 看起来它需要一个通用对象
  • 好的,但不是任何通用对象。它需要一个存在 W[D] 的 D。

标签: scala generics couchdb


【解决方案1】:

只是为了测试,你能否将你的类 Summoner 重命名为 $Summoner 并再次测试。 couchdb-scala 的代码尝试使用 getCanonicalName 获取名称,并抛出 java.lang.InternalError: Malformed class name。太棒了..不是吗?

【讨论】:

    猜你喜欢
    • 2012-12-06
    • 1970-01-01
    • 2014-06-22
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 2012-10-23
    • 2019-03-02
    • 1970-01-01
    相关资源
    最近更新 更多