我想找到一种在 scala 中的一些现有类中定义新方法的方法。
例如,我认为 asInstanceOf[T]
方法名称太长,我想将其替换为 as[T].
一个直接的方法可以是:
class WrappedAny(val a: Any) {
def as[T] = a.asInstanceOf[T]
}
implicit def wrappingAny(a: Any): WrappedAny = new WrappedAny(a)
有没有更自然、代码更少的方法?
另外,当我尝试这个时会发生一件奇怪的事情:
scala> class A
defined class A
scala> implicit def toA(x: Any): A = x
toA: (x: Any)A
scala> toA(1)
控制台挂起。看来
toA(Any)
不应该通过类型检查阶段,当它不是隐式时也不能。并且将所有代码放入外部源代码中也会产生同样的问题。这怎么发生的?它是编译器的错误(版本 2.8.0)吗?
最佳答案
您的拉皮条方法在技术上没有任何问题 Any
,尽管我认为这通常是不明智的。同样,有一个原因 asInstanceOf
和 isInstanceOf
被如此冗长地命名;这是为了阻止您使用它们!几乎可以肯定有一种更好的、静态类型安全的方式来做任何你想做的事情。
关于导致控制台挂起的示例:toA
的声明类型是 Any => A
,但您已将其结果定义为 x
,其类型为 Any
,而不是 A
.这怎么可能编译?好吧,请记住,当出现明显的类型错误时,编译器会四处寻找任何可用的隐式转换来解决问题。在这种情况下,它需要一个隐式转换 Any => A
...并找到一个:toA
!所以原因toA
类型检查是因为编译器隐式将其重新定义为:
implicit def toA(x: Any): A = toA(x)
...当您尝试使用它时,这当然会导致无限递归。
关于scala - 将方法注入(inject)现有类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4213239/