我有一个数组,我可以这样做:
myArr.lift(0)
…它让我可以选择索引0处的值
那么这里到底发生了什么?当我试图去解除定义,IDE带我到PartialFunction,我看到数组不继承它。
使用升降机的用途是什么?
确实,Array
是原生原生的JVM,并且没有任何lift
方法。
然而,在Scala中,我们有隐式转换和扩展方法,当我们能够调用未为某些类型定义的方法时,这是我们期望发现的。
如果你在IntelliJ中编写代码,并使用一个神奇的快捷方式来显示隐式(也可以在metals中使用),你会看到你的代码变成了例如(假设数组是int型):
wrapIntArray(myArr).lift(0)
其中wrapIntArray
在scala.Predef
中定义为
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)
这样的集合中的值,你就像使用函数一样使用它,但由于它不是一个全部映射,它应该是一个部分函数。
对于PartialFunction
slift
只是一个很好的实用程序,返回Option[Value]
而不是Value
或Exception
上的apply
,你刚刚得到,因为WrappedArray
像任何其他集合继承它。