scala – 数据集过滤器:eta扩展不会自动完成
如果我有一个简单的Int
Scala集合,我定义了一个简单的方法isPositive,如果该值大于0则返回true,那么我可以将该方法传递给集合的filter方法,如下例所示
def isPositive(i: Int): Boolean = i > 0 val aList = List(-3,-2,-1,1,2,3) val newList = aList.filter(isPositive) > newList: List[Int] = List(1,3) 因此,据我所知,编译器能够通过执行eta扩展自动将方法转换为函数实例,然后将此函数作为参数传递. 但是,如果我使用Spark数据集做同样的事情: val aDataset = aList.toDS val newDataset = aDataset.filter(isPositive) > error 它失败了众所周知的“缺少方法参数”错误.为了使它工作,我必须使用“_”显式地将方法转换为函数: val newDataset = aDataset.filter(isPositive _) > newDataset: org.apache.spark.sql.Dataset[Int] = [value: int] 虽然使用地图它按预期工作: val newDataset = aDataset.map(isPositive) > newDataset: org.apache.spark.sql.Dataset[Boolean] = [value: boolean] 调查签名,我看到Dataset过滤器的签名与List的过滤器非常相似: // Dataset: def filter(func: T => Boolean): Dataset[T] // List (Defined in TraversableLike): def filter(p: A => Boolean): Repr 那么,为什么编译器不为数据集的过滤操作进行eta扩展呢? 解决方法
这是由于重载方法和ETA扩展的性质.
Eta-expansion between methods and functions with overloaded methods in Scala解释了为什么会失败.
它的要点如下(强调我的):
…..
正如@DanielDePaula指出的那样,我们在DataSet.map中没有看到这种效果的原因是因为重载方法实际上需要额外的Encoder [U]参数: def map[U : Encoder](func: T => U): Dataset[U] = withTypedPlan { MapElements[T,U](func,logicalPlan) } def map[U](func: MapFunction[T,U],encoder: Encoder[U]): Dataset[U] = { implicit val uEnc = encoder withTypedPlan(MapElements[T,logicalPlan)) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |