我希望使用Pimp my Library模式使用返回Field[T]
的方法扩展参数化特征this.type
。但我坚持编译器错误。我尝试了一些变种,但没有成功。
我做错了吗?或者要求不可能?
这是我的测试示例:
trait Field[T]
class IntField extends Field[Int] {
def getInt = 5
}
// Variant 1: return field.type
object Var1 {
implicit class RichField[T](val field: Field[T]) {
def bar(fn: T => String): field.type = {
// some actions using T
field
}
}
new IntField().bar(_.toString).getInt // Error: value getInt is not a member of Field[Int]
}
// Variant 2: use two type parameters
object Var2 {
implicit class RichField[T, F <: Field[T]](val field: F) {
def bar(fn: T => String): F = {
// some actions using T
field
}
}
new IntField().bar(_.toString).getInt // <-- Error: value bar is not a member of IntField
}
// Variant 3: use higher kinds
object Var3 {
import scala.language.higherKinds
implicit class RichField[F[X] <: Field[X], T](val field: F[T]) {
def bar(fn: T => String): F[T] = {
// some actions using T
field
}
}
new IntField().bar(_.toString).getInt // <-- Error: value getInt is not a member of Field[Int]
}
更新:参数T
对方法bar
很重要,不能忽略。
答案 0 :(得分:2)
在变体2中,您没有在任何地方使用T
。只需删除它,编译器就不会再混淆了:
implicit class RichField[F <: Field[_]](val field: F) {
def bar: F = field
}
更新:如果您确实需要T
,正如您在评论中提到的那样,可能的解决方法是:
implicit class RichField[T, F <: Field[_]](val field: F with Field[T]) {
def bar(fn: T => String): F = {
// some actions using T
field
}
}
这里有一个证明它按预期工作(使用toString
,因为在你的例子中,toString
在每个类都可用,所以即使编译器推断{{1},也不是一个好的测试代码将编译):
Any