&引用;加上;Scala的等价语句?

&引用;加上;Scala的等价语句?,scala,Scala,也许是Scala学习者的无聊思考,但是。。。在我的修补中,我写了以下内容: ( n.child.size > 0 ) && ( n.child.filter( ! _.isInstanceOf[Text] ).size == 0 ) ('n'是scala.xml.Node,但这并不重要。特定的逻辑也不重要。) 调用child()两次不太好,所以我打算更改它: val list = n.child ( list.size > 0 ) && ( list

也许是Scala学习者的无聊思考,但是。。。在我的修补中,我写了以下内容:

( n.child.size > 0 ) && ( n.child.filter( ! _.isInstanceOf[Text] ).size == 0 )
('n'是scala.xml.Node,但这并不重要。特定的逻辑也不重要。)

调用child()两次不太好,所以我打算更改它:

val list = n.child
( list.size > 0 ) && ( list.filter( ! _.isInstanceOf[Text] ).size == 0 )
但是考虑到我非常欣赏能够在不需要声明中间变量的情况下过滤()和映射()之类的东西,我发现这很难闻。真是太。。。所以那是爪哇语!:p

唉,翻阅SO、谷歌和ScalaDocs(尤其是Any和AnyRef),这本书没有找到任何合适的答案。我希望能有这样的结果:

n.child{ list => ( list.size > 0 ) && ( list.filter( ! _.isInstanceOf[Text] ).size == 0 ) }
甚至

n.child.with{ list => ... }
这样的东西存在吗?或者我只是陷入了一种不稳定的狂热中?

“with”当然是Scala中的一个保留字,所以我们从Lisp和Haskell中类似的绑定形式将其称为“let”。事实证明,“let”只是编写函数应用程序的一种倒退方式

def let[A,B](param:A)(body: A=>B):B = body(param)

let(n.child){list=> ...}

如果绑定变量只使用一次,您当然可以使用匿名函数形式,但这与目的背道而驰。

如果您只想限制中间变量的范围,也可以在谓词周围创建一个块:

val n = getNodeByMagic()
val passesTest = {
    val child = n.child
    child.length == 0 && !child.filter(_.isInstanceOf[Text]).isEmpty
}
// child is not defined outside of the block

为此,您可以使用
match

n.child match {
case list => ( list.size > 0 ) && ( list.filter( ! _.isInstanceOf[Text] ).size == 0 )
}

Scala 2.13
开始,标准库现在提供了一种完全符合这一需要的链接操作方法:

import scala.util.chaining._

n.child.pipe(list => list.size > 0 && list.filterNot(_.isInstanceOf[Text]).size == 0)

n.child
的值被“输送”到感兴趣的函数。

此外,过滤器/大小的事情效率低下。将其替换为list.forall(u.isInstanceOf[Text]),这是我最初的想法,但它不是完全相同的事情:我需要知道列表只包含文本元素,并且是非空的。我刚刚发现Iterable的“count”可以把事情缩短一点:(n.child.size>0)和&(n.child.count(!\u.isInstanceOf[Text])==0)甚至更好:!(n.child.isEmpty | | n.child.exists(!.isInstanceOf[Text])对不起,不清楚。我是说!n、 child.isEmpty&&n.child.forall(u.isInstanceof[Text]),通过DeMorgans定律和以下事实,它与上一个相同!x、 exists(!y)与x相同。forall(y)我也有同样的问题,但后来我了解到这种val的使用非常有益,与java的可变VAR不可相比。特别是如果您使用更好的名称,在本例中为“val child=n.child”,这会使代码更加明显。很好!现在,我有了一个新的Scala语法来解决这个问题。:-)您也可以使用pimp my library。它的长度不是与“val list=n.child”“list…”相同吗?更准确地说,它相当于{val list=n.child;list…},用大括号将其作为一个表达式。它应该在标准库中:)这个库中现在有一个Tap的实现:
Tap(a=>B)
方法可能应该是
tap(A=>Unit):A
以允许进一步的链接或分配,例如:
val order=new order()。tap{o=>o.setStatus('UNPAID')}
n.child match {
case list => ( list.size > 0 ) && ( list.filter( ! _.isInstanceOf[Text] ).size == 0 )
}
import scala.util.chaining._

n.child.pipe(list => list.size > 0 && list.filterNot(_.isInstanceOf[Text]).size == 0)