我想找到一种方法来在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)吗?
答案 0 :(得分:8)
你对拉皮条Any
的方法没有任何技术上的错误,尽管我认为这通常是不明智的。同样地,asInstanceOf
和isInstanceOf
如此详细地命名是有原因的;这是为了阻止你使用它们!几乎可以肯定,这是一种更好的,静态类型安全的方式来做任何你想做的事情。
关于导致控制台挂起的示例:声明的toA
类型为Any => A
,但您已将其结果定义为x
,其类型为Any
},而不是A
。这怎么可能编译?好吧,请记住,当出现明显的类型错误时,编译器会四处寻找任何可用的隐式转换来解决问题。在这种情况下,它需要隐式转换Any => A
...并找到一个:toA
!因此toA
类型检查的原因是因为编译器隐式地将其重新定义为:
implicit def toA(x: Any): A = toA(x)
...当你尝试使用它时,当然会导致无限递归。
答案 1 :(得分:3)
在第二个示例中,您将Any
传递给必须返回A
的函数。但是它永远不会返回A
但是传入的Any
相同。然后编译器尝试应用隐式转换,而隐式转换又不返回A
而是Any
,并且等等。
如果您将toA定义为不隐式,则得到:
scala> def toA(x: Any): A = x
<console>:6: error: type mismatch;
found : Any
required: A
def toA(x: Any): A = x
^
答案 2 :(得分:1)
实际上,之前已经在Scala列表中对此进行了讨论。 pimp我的类模式确实有点冗长,也许,可能有一种方法可以在不引入新关键字的情况下清理语法。
关于新关键字的一点是,Scala的目标之一是通过库使语言可扩展,而不是将语言变成一个巨大的想法,这些想法通过某人的标准“足够有用,可以添加到语言中”,同时,让其他想法变得不可能,因为它们被认为不合适和/或不够普遍。
无论如何,到目前为止还没有任何结果,我还没有听说有任何进展正在朝着这个目标前进。欢迎您通过其邮件列表加入社区,并为其发展做出贡献。