gpt4 book ai didi

scala - 有没有办法将 Scala 类 "enrich"而不将代码包装到另一个对象中?

转载 作者:行者123 更新时间:2023-12-02 09:26:55 30 4
gpt4 key购买 nike

在 Scala 2.9 中,要将自定义方法添加到库类(丰富或“pimp”它),我必须编写如下内容:

object StringPimper {
implicit def pimpString(s: String) = new {
def greet: String = "Hello " + s
}
}
随着 Scala 2.10 的发布,我了解到它引入了隐式类定义,从理论上讲,它的目的是通过消除返回匿名类对象的隐式方法的需要来简化上述任务。我认为这将使我能够写作

implicit class PimpedString(s: String) {
def greet: String = "Hello " + s
}

这对我来说看起来更漂亮。但是,这样的定义会导致编译错误:

`implicit' modifier cannot be used for top-level objects

通过再次将代码包装在对象中可以解决这个问题:

object StringPimper {
implicit class PimpedString(s: String) {
def greet: String = "Hello " + s
}
}

不用说,这几乎抵消了改进的感觉。

那么,有没有办法把它写得更短呢?摆脱包装对象?

我实际上有一个 MyApp.pimps 包,所有皮条客都在其中(我没有太多,如果有的话我会使用一些单独的包),而且我厌倦了导入MyApp.pimps.StringPimper._ 而不是 MyApp.pimps.PimpedStringMyApp.pimps._。当然,我可以将所有隐式类放在一个包装对象中,但这意味着将它们全部放在一个文件中,这将是相当长的 - 相当丑陋的解决方案。

最佳答案

现在的标准术语是丰富。我不确定为什么以前没有,因为使用它的库方法被命名为 RichString 之类的东西。不是PimpedString .

无论如何,你不能将隐式类放在任何东西中,但是为了使用隐式,你需要方法,并且你不能将方法放在任何东西中。但你可以作弊来获取 pimps 中的所有内容。 .

// This can go in one file
trait ImplicitsStartingWithB {
implicit class MyBoolean(val bool: Boolean) { def foo = !bool }
implicit class MyByte(val byte: Byte) { def bar = byte*2 }
}

// This can go in another file
trait ImplicitsStartingWithS {
implicit class MyShort(val short: Short) { def baz = -short }
implicit class MyString(val st: String) { def bippy = st.reverse }
}

// This is a third file, if you want!
object AllImplicits extends ImplicitsStartingWithB with ImplicitsStartingWithS {}

scala> import AllImplicits._
import AllImplicits._

scala> true.foo
res0: Boolean = false

您还可以使用 pimps 来执行此操作包对象——通常您会放置一个名为 package.scala 的文件在名为 pimps 的目录中,然后

package object pimps extends /* blah blah ... */ {
/* more stuff here, if you need it */
}

需要注意的是,值类作为一项新功能,具有相当多的限制。有些是不必要的,但如果您想避免分配新的 MyBoolean类(JVM 通常可以极大地优化它,但通常不会达到裸方法调用的程度),您必须解决这些限制。在这种情况下,

// In some file, doesn't really matter where
class MyBoolean(val bool: Boolean) extends AnyVal { def foo = !bool }

package object pimps {
def implicit EnrichWithMyBoolean(b: Boolean) = new MyBoolean(b)
}

这不会节省您的工作量(但运行速度更快)。

关于scala - 有没有办法将 Scala 类 "enrich"而不将代码包装到另一个对象中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14802517/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com