Scala:提升数组



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

myArr.lift(0)

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

那么这里到底发生了什么?当我试图去解除定义,IDE带我到PartialFunction,我看到数组不继承它。

使用升降机的用途是什么?

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

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

如果你在IntelliJ中编写代码,并使用一个神奇的快捷方式来显示隐式(也可以在metals中使用),你会看到你的代码变成了例如(假设数组是int型):

wrapIntArray(myArr).lift(0)

其中wrapIntArrayscala.Predef中定义为

(参见数组到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.Int,scala.Char和其他原语
  • scala.Predef-将Map别名为scala.collection.immutable.Map,在Array周围添加包装,让您使用println而不是scala.Console。println等
  • java.lang-导入Throwable

(我写了"default"因为你可以用-Yimports来改变它,但如果你没有经验丰富的开发人员和良好的文档,我不建议你自定义predef)。

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

  • 您可以使用apply来获取值,但如果索引/键错误(例如vector(10)),则有Exception的风险
  • 您可以使用applyOrElse来获取该值或一些备用值
  • 您可以检查isDefinedAt是否有键/索引,因此您的集合可以用于任何期望PartialFunction的东西,例如coll1.collect(coll2)coll1的所有元素映射到coll2的值,将coll1的值作为用于查询coll2的键/索引

推理很简单-如果你正在访问像coll(index)这样的集合中的值,你就像使用函数一样使用它,但由于它不是一个全部映射,它应该是一个部分函数。

对于PartialFunctionslift只是一个很好的实用程序,返回Option[Value]而不是ValueException上的apply,你刚刚得到,因为WrappedArray像任何其他集合继承它。

最新更新