加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 如何将do-nothing处理程序设置为by-name参数?

发布时间:2020-12-16 18:24:08 所属栏目:安全 来源:网络整理
导读:我定义了一个方法treeNode来创建一个节点,它可以有子节点.简化的代码是: def treeNode(text:String) (children: = Any) { val b = new TreeNode(text) children} 当我使用这种方法时,我必须写: treeNode("aaa") { treeNode("bbb") {} treeNode("ccc") {}}
我定义了一个方法treeNode来创建一个节点,它可以有子节点.简化的代码是:

def treeNode(text:String) (children: => Any) {
    val b = new TreeNode(text)
    children
}

当我使用这种方法时,我必须写:

treeNode("aaa") {
    treeNode("bbb") {}
    treeNode("ccc") {}
}

您可以看到他们没有子节点的叶节点,但它们必须有一个空块{}.

有没有办法给参数children:=>任何默认的do-nothing值,我可以将代码编写为:

treeNode("aaa") {
    treeNode("bbb")
    treeNode("ccc")
}

帮助?

解决方法

问题不在于你不能给它一个do-nothing(默认)值;问题是,即使你这样做,具有多个参数块的函数必须至少具有每个块的括号或大括号.

有一个例外:根本不需要引用隐式参数块.不幸的是,你不允许使用按名称调用的隐式参数,即使你是这样,你的签名也会允许任何随机的隐式参数在那个地方工作!

现在,有一种方法,我将展示完整性,但我建议(假设您不只是想要另一个名称,如leafNode),您只需将尾随{}留在那里.

如果执行以下操作,您可以获得所需的语法.首先,您需要一个隐式参数,但是您将它设置为包装类(可以使用已经存在的Function0,但是下一步可能会产生意想不到的后果):

trait AnyByName { def eval: Any }
def treeNode(text: String)(implicit children: AnyByName) = (text,children.eval)

现在你需要两件事 – 你需要能够将一个名字Any转换成你的新特性,你需要有一个隐含的do-nothing可用的东西.所以我们

implicit val nameForDoingNothing = new AnyByName { def eval = () }
implicit def wrap_any_by_name(a: => Any) = new AnyByName { def eval = a }

现在我们恢复你以后的行为:

scala> treeNode("Hi")
res1: (String,Any) = (Hi,())

scala> treeNode("Hi") { treeNode("there") }
res2: (String,(there,()))

(在你的例子中,你不返回任何东西;我在这里,以证明它有效.)

不过,为了避免某些问题,这是很多工具,这就是为什么我建议只做这个,如果你预计这是一个非常频繁使用的DSL,并且这两个名字是不可接受的. (另外,如果你期望它被大量使用,treeNode可能只是一个名字的痛苦;我建议只是节点.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读