Scala:提升数组

Scala: lift on Array

所以我有一个数组,我可以这样做:

myArr.lift(0)

...它让我可以选择索引 0 处的值。

那么这里到底发生了什么?当我尝试去提升定义时,IDE 将我带到 PartialFunction,我看到 Array 没有继承自它。

使用电梯的用例是什么?

确实 Array 是 JVM 原生的原始方法,没有任何 lift 方法。

但是在 Scala 中我们有隐式转换和扩展方法,当我们能够调用未为某些类型定义的方法时,这就是我们期望找到的。

如果您在 IntelliJ 中编写代码并使用神奇的快捷方式 for showing implicits (also available in metals),您会看到您的代码变成了例如(假设为整数数组):

wrapIntArray(myArr).lift(0)

其中 wrapIntArrayscala.Predef 中定义(参见 Array to ArraySeq 部分)为

implicit def wrapIntArray(xs: Array[Int]): WrappedArray[Int] = if (xs ne null) new WrappedArray.ofInt(xs) else null

(在 Scala 2.13 中 WrappedArray 已被弃用并成为 ArraySeq 的别名)。

如果您好奇为什么它在您的范围内,请记住默认情况下 Scala 编译器从以下路径导入所有定义:

  • scala - 导入所有 scala.Intscala.Char 和其他基元
  • scala.Predef - 将 Map 别名为 scala.collection.immutable.Map,在 Array 周围添加包装器,让您使用 println 而不是 scala.Console.println,等等
  • java.lang - 导入像 Throwable
  • 这样的东西

(我写“默认”是因为您可以使用 -Yimports 更改它,但如果您没有经验丰富的开发人员和良好的文档,我不会推荐自定义预定义)。

lift 的用例是什么?基本上所有 Scala collection 都有一些共同的特征,PartialFunction 就是其中之一:

  • 您可以使用 apply 获取值,但如果 index/key 错误(例如 vector(10)
  • ,则冒着 Exception 的风险
  • 您可以使用 applyOrElse 来获取值或一些回退值
  • 你可以用 isDefinedAt 检查是否有 key/index 的东西,所以你的 collection 可以用于任何期望 PartialFunction 的东西,例如coll1.collect(coll2) 会将 coll1 的所有元素映射到 coll2 的值,将 coll1 的值视为 keys/indices 用于查询 coll2

推理非常简单 - 如果您像 coll(index) 一样访问 collection 中的值,您就像函数一样使用它,但由于它不是一个完整的映射,它应该是一个部分函数。

For PartialFunctions lift 只是 return Option[Value] 的一个很好的实用程序,而不是 [=31] 上的 ValueException =],你刚刚得到,因为 WrappedArray 像任何其他 collection 继承它一样。