我正在使用一个类(我无法修改),其中包含一个接收Any类型值作为参数的方法,如下例所示:
class Foo(value: Int) {
def +(other: Any): Foo = ???
}
我希望在方法+()
与特定类型一起使用时添加自定义实现。我希望能够做到这样的事情:
implicit class RichFoo(foo: Foo) {
def +(other: Int): Foo = ???
}
// or
implicit class RichFoo(foo: Foo) {
def +[T <: Bar](other: T): T = ???
}
但是,这些方法不起作用。
是否可以不延长原班级?
答案 0 :(得分:3)
没有
对于编译器,隐式转换和其他重写规则(如.desktop {
display: flex;
align-items: center;
}
.root-nav-links {
margin: 0 15px;
padding: 2px 6px;
}
周围的那些)是各种各样的“最后手段”。它们仅在代码尚未按原样检查时应用。执行Dynamic
时,编译器已经知道foo + x
需要+
,因此它甚至不会尝试查找隐含。如果您执行了Any
,并且foo - x
没有正确类型的Foo
,那么编译器只会搜索转换。
相反,您可以使用-
中不存在但add
中存在的新名称(可能为Foo
)创建方法。但是,这不会阻止您执行RichFoo
而不是foo + 1
,因为这两种方法都有效。
foo add 1
答案 1 :(得分:2)
您可以使用幻像类型来跟踪可转换的内容。
SetItemVisibilityByPattern(resultField, "(4K[24A]|685|923).*")
给定的东西:
scala> trait Tagged[B]
defined trait Tagged
scala> type Of[+A, B] = A with Tagged[B]
defined type alias Of
scala> class Tagger[B] { def apply[A](a: A): A Of B = a.asInstanceOf[A Of B] }
defined class Tagger
scala> object tag { def apply[B]: Tagger[B] = new Tagger[B] }
defined object tag
和标记特征:
scala> case class C(i: Int) { def +(x: Any): C = C(i + x.toString.toInt) }
defined class C
通常:
scala> trait CC
defined trait CC
这有效:
scala> C(42) + "17"
res0: C = C(59)
但不是这样:
scala> val cc = tag[CC](C(42))
cc: Of[C,CC] = C(42)
也许这个:
scala> val cc = tag[CC](C(42): Any)
java.lang.ClassCastException: C cannot be cast to Tagged
... 29 elided
然后:
scala> val cc = tag[CC](C(42): Serializable)
cc: Of[Serializable,CC] = C(42)
异常:
scala> implicit class XC(v: Serializable Of CC) {
| def +(x: Any): C Of CC = tag[CC] {
| println("OK")
| v.asInstanceOf[C] + x
| }}
defined class XC
肯定有更好的方法可以做到这一点:
scala> val valueAdded = cc + "17"
OK
valueAdded: Of[C,CC] = C(59)
因为它毁了它:
scala> implicit def untagit(x: Serializable Of CC): C Of CC = tag[CC](x.asInstanceOf[C])
untagit: (x: Of[Serializable,CC])Of[C,CC]
scala> cc.i
res9: Int = 42