我想创建一个通用接口,它隐藏了产品密钥上hash
函数的实现(用于查找产品以及产品本身范围之外的各种缓存和计算)。我想将哈希函数的具体实现与实现该接口的特定阅读器联系起来。我出于各种一致性原因这样做,因为产品存储在缓存中,将来可能会迁移,我想确保查找始终使用相同的hash
。我有一些关于如何以这种方式编写泛型的语法问题。
例如,这种类型的层次结构我有语法问题:
trait Hash {
type U
type V
def hash(u:U) : V
}
trait Product[hasher <: Hash] {
val key : hasher#U
// hasher.hash(x : U) => V
def hashKey : hasher#V
}
trait ProductReader[product <: Product] { // error: type 'Product' takes parameters - but I don't want to define them at this point yet...
def getByKey(key : U) : Product
def getByHashed(hash : V) : Product
}
示例用法是:
object MyHash extends Hash[String,Long] {
def hash(key : String) : Long = mySpecialHash(key)
}
// implements serialization (together with the hasher)
class MyProduct[MyHash[String,Long]](val key : String {
def hashKey : Long = MyHash.hash(key)
}
class MyProductReader[MyProducts[MyHash[String,Long]] {
def getByKey(key : String) : MyProduct[MyHash[String,Long]] = ....
def getByHashed(hash : Long) : MyProduct[MyHash[String,Long]] = ...
}
答案 0 :(得分:0)
如果您不想在声明点绑定特定的Product
,则可以使用抽象类型成员而不是泛型类型参数:
trait Hash {
type U
type V
def hash(u: U): V
}
trait Product {
type Hasher <: Hash
val key: Hasher#U
def hashKey: Hasher#V
}
trait ProductReader[P <: Product] {
def getByKey(key: P#Hasher#U): P
def getByHashed(hash: P#Hasher#V): P
}
object MyHash extends Hash {
override type U = String
override type V = Long
def hash(key: String): Long = ???
}
class MyProduct(val hasher: MyHash.type) extends Product {
override type Hasher = hasher.type
def hashKey: Long = MyHash.hash(key)
override val key: String = "MyProduct"
}
class MyProductReader extends ProductReader[MyProduct] {
override def getByKey(key: String): MyProduct = ???
override def getByHashed(hash: Long): MyProduct = ???
}
另一种方法是添加其他类型参数。这实际上取决于你的味道,我认为在这种情况下使用类型成员最终会减少冗长。
答案 1 :(得分:0)
您可以向ProductReader
添加第二个参数类型trait Hash {
type U
type V
def hash(u:U) : V
}
trait Product[hasher <: Hash] {
val key : hasher#U
// hasher.hash(x : U) => V
def hashKey : hasher#V
}
trait ProductReader[hasher <: Hash, product <: Product[hasher]] {
def getByKey(key : hasher#U) : product
def getByHashed(hash : hasher#V) : product
}
现在,使用您的示例:
object MyHash extends Hash {
type U = String
type V = Long
def hash(key : String) : Long = key.toLong
}
class MyProduct(val hasher: MyHash.type) extends Product[MyHash.type] {
def hashKey: Long = hasher.hash(key)
val key: String = "MyProduct"
}
class MyProductReader extends ProductReader[MyHash.type, MyProduct] {
def getByKey(key : String) : MyProduct = ???
def getByHashed(hash : Long) : MyProduct = ???
}