Scala 如何指定在类型参数中传递的类具有某个伴生对象?
我有两个特点:Scala 如何指定在类型参数中传递的类具有某个伴生对象?,scala,generics,polymorphism,traits,companion-object,Scala,Generics,Polymorphism,Traits,Companion Object,我有两个特点: sealed trait DbValue { type R type T <: DbValue def content(): R def copy(newContent: R = content): Option[T] def toString(): String } sealed trait DbValueOps { type R type T <: DbValue def apply(newContent: R): Option[
sealed trait DbValue {
type R
type T <: DbValue
def content(): R
def copy(newContent: R = content): Option[T]
def toString(): String
}
sealed trait DbValueOps {
type R
type T <: DbValue
def apply(newContent: R): Option[T]
def fromString(newContent: String): Option[T]
def isValidContent(newContent: R): Boolean
}
但是,当我尝试创建这样一个列时,使用:Column[DbString](“name”)
我得到一个错误:
type参数[database.DbString]不符合方法apply的类型参数界限[TClassX
和它的伴生对象X
从OOP的角度来看完全不相关(除了它们的成员“可以看到”彼此,即使它们是私有的)类X
的类型是X
,对象X
的类型是X.Type
,这些类型也不相关
试一试
case-class-Column[TclassX
和它的伴生对象X
从OOP的角度来看是完全不相关的(除了它们的成员即使是私有的也可以“看到”彼此)类X
的类型是X
,对象X
的类型是X.Type
,这些类型也不相关
试一试
case class Column[T我就是这样解决的:
traits是由一个对象实现的,ops trait是由我相信的typeclass实例实例化的
sealed trait DbValue[R, T <: DbValue[R, T]] {
def content(): R
def copy(newContent: R = content): Option[T]
def toString(): String
}
sealed trait DbValueOps[R, T <: DbValue[R, T]] {
def apply(newContent: R): Option[T]
def fromString(newContent: String): Option[T]
def isValidContent(newContent: R): Boolean
def fromDbValue[U, V <: DbValue[U, V]](dbValue: V): Option[T] = fromString(dbValue.toString())
}
DbValue[R,T这就是我最终解决它的原因:
traits是由一个对象实现的,ops trait是由我相信的typeclass实例实例化的
sealed trait DbValue[R, T <: DbValue[R, T]] {
def content(): R
def copy(newContent: R = content): Option[T]
def toString(): String
}
sealed trait DbValueOps[R, T <: DbValue[R, T]] {
def apply(newContent: R): Option[T]
def fromString(newContent: String): Option[T]
def isValidContent(newContent: R): Boolean
def fromDbValue[U, V <: DbValue[U, V]](dbValue: V): Option[T] = fromString(dbValue.toString())
}
DbValue[R,T我可以强制DbValueOps是DbValue的伴生对象吗?因为这样我可以使T成为DbString,而U成为与DbInt关联的伴生对象。也许可以通过更改traits的类型签名?@FrederikBaetens我可以强制DbValueOps是DbValue的伴生对象吗?因为这样我就可以使T成为DbString,而U成为与DbInt相关联的伴生对象。也许可以通过更改traits的类型签名?@FrederikBaetens
case class Column[T <: DbValue, U <: DbValueOps](...
Column[DbString, DbString.type]("name")
sealed trait DbValue[R, T <: DbValue[R, T]] {
def content(): R
def copy(newContent: R = content): Option[T]
def toString(): String
}
sealed trait DbValueOps[R, T <: DbValue[R, T]] {
def apply(newContent: R): Option[T]
def fromString(newContent: String): Option[T]
def isValidContent(newContent: R): Boolean
def fromDbValue[U, V <: DbValue[U, V]](dbValue: V): Option[T] = fromString(dbValue.toString())
}
case class Column[R, T <: DbValue[R, T]] private (
val name: String,
val cells: Vector[Option[T]] = Vector(),
val blankAllowed: Boolean = true,
val defaultValue: Option[T] = None,
)(implicit ops: DbValueOps[R, T]) extends ColumnStringOps {