Scala:需要类类型但是T找到了

时间:2014-06-11 21:34:56

标签: scala types scala-2.10 traits

我发现了这个特定问题的类似问题,但问题是由于有人试图直接实例化T。在这里,我尝试创建一个特性,这是一个通用接口,用于扩展类并使用classOf[T]自动将它们存储在Riak等数据库中。使用Scala 2.10。

这是我的代码:

trait RiakWriteable[T] {

  /**
   * bucket name of data in Riak holding class data
   */
  def bucketName: String

  /**
   * determine whether secondary indices will be added
   */
  def enable2i: Boolean

  /**
   * the actual bucket
   */
  val bucket: Bucket = enable2i match {
    case true => DB.client.createBucket(bucketName).enableForSearch().execute()
    case false => DB.client.createBucket(bucketName).disableSearch().execute()
  }

  /**
   * register the scala module for Jackson
   */
  val converter = {
    val c = new JSONConverter[T](classOf[T], bucketName)
    JSONConverter.registerJacksonModule(DefaultScalaModule)
    c
  }

  /**
   * store operation
   */
  def store = bucket.store(this).withConverter(converter).withRetrier(DB.retrier).execute()

  /**
   * fetch operation
   */
  def fetch(id: String): Option[T] = {
    val u = bucket.fetch(id, classOf[T]).withConverter(converter).withRetrier(DB.retrier).r(DB.N_READ).execute()
    u match {
      case null => None
      case _ => Some(u)
    }
  }

}

编译器错误为class type required but T found

示例用法(伪代码):

class Foo

object Foo extends RiakWriteable[Foo]

Foo.store(object)

所以我猜测T的清单没有被正确定义。我是否需要在某处隐式定义它?

谢谢!

1 个答案:

答案 0 :(得分:1)

这是一个中介解决方案,虽然它省略了converter注册(我可能会永久保留此用例,但还不确定)。

/**
 * trait for adding write methods to classes
 */
trait RiakWriteable[T] {

  /**
   * bucket name of data in Riak holding class data
   */
  def bucketName: String

  /**
   * determine whether secondary indices will be added
   */
  def enable2i: Boolean

  /**
   * the actual bucket
   */
  val bucket: Bucket = enable2i match {
    case true => DB.client.createBucket(bucketName).enableForSearch().execute()
    case false => DB.client.createBucket(bucketName).disableSearch().execute()
  }

  /**
   * store operation
   */
  def store(o: T) = bucket.store(o).withRetrier(DB.retrier).execute()

  /**
   * fetch operation
   */
  def fetch(id: String)(implicit m: ClassTag[T]) = {
    val u = bucket.fetch(id, classTag[T].runtimeClass).withRetrier(DB.retrier).r(DB.N_READ).execute()
    u match {
      case null => None
      case _ => Some(u)
    }
  }

}