将方法注入到现有类中

发布于 2024-10-02 23:02:24 字数 607 浏览 2 评论 0原文

我想找到一种方法在 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)的错误吗?

I want to come out a way to define a new method in some existing class in scala.

For example, I think the asInstanceOf[T] method has too long a name, I want to replace it with as[T].

A straight forward approach can be:

class WrappedAny(val a: Any) {
  def as[T] = a.asInstanceOf[T]
}

implicit def wrappingAny(a: Any): WrappedAny = new WrappedAny(a)

Is there a more natural way with less code?

Also, a strange thing happens when I try this:

scala> class A

defined class A

scala> implicit def toA(x: Any): A = x

toA: (x: Any)A

scala> toA(1)

And the console hang. It seems that toA(Any) should not pass the type checking phase, and it can't when it's not implicit. And putting all the code into a external source code can produce the same problem. How did this happen? Is it a bug of the compiler(version 2.8.0)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱殇璃 2024-10-09 23:02:24

从技术上讲,你拉皮条 Any 的方法没有任何问题,尽管我认为这通常是不明智的。同样,asInstanceOfisInstanceOf 的命名如此冗长也是有原因的;这是为了阻止您使用它们!几乎可以肯定,有一种更好的、静态类型安全的方法来完成您想要做的任何事情。

关于导致控制台挂起的示例:toA 的声明类型为 Any => A,但您已将其结果定义为 x,其类型为 Any,而不是 A。这怎么可能编译?好吧,请记住,当发生明显的类型错误时,编译器会四处寻找任何可用的隐式转换来解决问题。在这种情况下,它需要隐式转换 Any => A...并找到一个:toA!所以 toA 类型检查的原因是因为编译器隐式地将其重新定义为:

implicit def toA(x: Any): A = toA(x)

...当您尝试使用它时,这当然会导致无限递归。

There's nothing technically wrong with your approach to pimping Any, although I think it's generally ill-advised. Likewise, there's a reason asInstanceOf and isInstanceOf are so verbosely named; it's to discourage you from using them! There's almost certainly a better, statically type-safe way to do whatever you're trying to do.

Regarding the example which causes your console to hang: the declared type of toA is Any => A, yet you've defined its result as x, which has type Any, not A. How can this possibly compile? Well, remember that when an apparent type error occurs, the compiler looks around for any available implicit conversions to resolve the problem. In this case, it needs an implicit conversion Any => A... and finds one: toA! So the reason toA type checks is because the compiler is implicitly redefining it as:

implicit def toA(x: Any): A = toA(x)

... which of course results in infinite recursion when you try to use it.

旧伤还要旧人安 2024-10-09 23:02:24

在第二个示例中,您将 Any 传递给必须返回 A 的函数。但是,它永远不会返回 A,而是返回您传入的相同 Any。然后,编译器会尝试应用隐式转换,而隐式转换又不会返回 A > 但任何,等等。

如果您将 toA 定义为非隐式,您将得到:

scala> def toA(x: Any): A = x           
<console>:6: error: type mismatch;
 found   : Any
 required: A
       def toA(x: Any): A = x
                            ^

In your second example you are passing Any to a function that must return A. However it never returns A but the same Any you passed in. The compiler then tries to apply the implicit conversion which in turn does not return an A but Any, and so on.

If you define toA as not being implicit you get:

scala> def toA(x: Any): A = x           
<console>:6: error: type mismatch;
 found   : Any
 required: A
       def toA(x: Any): A = x
                            ^
三月梨花 2024-10-09 23:02:24

碰巧的是,这个问题之前已经在 Scala 列表中讨论过。皮条客我的类模式确实有点冗长,也许,可能有一种方法可以在不引入新关键字的情况下清理语法。

关于新关键字的一点是,Scala 的目标之一是通过库使语言可扩展,而不是将语言变成一大堆想法,通过某人的“有用到足以添加到语言中”的标准,同时,时间,使其他想法变得不可能,因为它们被认为不够有用和/或不够普遍。

不管怎样,到目前为止还没有任何进展,我也没有听说有任何工作正在朝着这个目标进行。欢迎您通过邮件列表加入社区并为其发展做出贡献。

As it happens, this has been discussed on Scala lists before. The pimp my class pattern is indeed a bit verbose for what it does, and, perhaps, there might be a way to clean the syntax without introducing new keywords.

The bit about new keywords is that one of Scala goals is to make the language scalable through libraries, instead of turning the language into a giant quilt of ideas that passed someone's criteria for "useful enough to add to the language" and, at the same time, making other ideas impossible because they weren't deemed useful and/or common enough.

Anyway, nothing so far has come up, and I haven't heard that there is any work in progress towards that goal. You are welcome to join the community through its mailing lists and contribute to its development.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文