Scala 3 — 书籍

扩展方法

语言
此文档页面特定于 Scala 3,并且可能涵盖 Scala 2 中不可用的新概念。除非另有说明,此页面中的所有代码示例均假定您使用的是 Scala 3。

在 Scala 2 中,可以使用 隐式类 实现类似的结果。


扩展方法允许您在类型定义后向类型添加方法,即允许您向封闭类添加新方法。例如,假设其他人创建了一个 Circle

case class Circle(x: Double, y: Double, radius: Double)

现在假设您需要一个 circumference 方法,但您无法修改其源代码。在术语推理概念引入编程语言之前,您唯一能做的事情就是像这样在单独的类或对象中编写一个方法

object CircleHelpers {
  def circumference(c: Circle): Double = c.radius * math.Pi * 2
}
object CircleHelpers:
  def circumference(c: Circle): Double = c.radius * math.Pi * 2

然后您将像这样使用该方法

val aCircle = Circle(2, 3, 5)

// without extension methods
CircleHelpers.circumference(aCircle)

但是使用扩展方法,你可以创建一个 circumference 方法来处理 Circle 实例

extension (c: Circle)
  def circumference: Double = c.radius * math.Pi * 2

在此代码中

  • Circle 是扩展方法 circumference 将被添加到其中的类型
  • c: Circle 语法让你可以在扩展方法中引用变量 c

然后在你的代码中,你可以像在 Circle 类中最初定义的那样使用 circumference

aCircle.circumference

导入扩展方法

想象一下,circumference 在包 lib 中定义,你可以通过以下方式导入它

import lib.circumference

aCircle.circumference

如果缺少导入,编译器也会通过显示以下详细的编译错误消息来支持你

value circumference is not a member of Circle, but could be made available as an extension method.

The following import might fix the problem:

   import lib.circumference

讨论

extension 关键字声明你即将在括号中放入的类型上定义一个或多个扩展方法。要对类型定义多个扩展方法,请使用此语法

extension (c: Circle)
  def circumference: Double = c.radius * math.Pi * 2
  def diameter: Double = c.radius * 2
  def area: Double = math.Pi * c.radius * c.radius

此页面的贡献者