如何让代理在埃菲尔的 {ARRAY}.do_if 工作?

How do I get agents to work in {ARRAY}.do_if in Eiffel?

我正在尝试在 Eiffel 中迭代一个数组。和 select 一些元素,使用 do_if.

我试过的。

my_method (list:ARRAY[INTEGER])
    local
        low : ARRAYED_LIST[INTEGER]
        piv : INTEGER
    do
    create low.make(0)

    --works for all, but not what I need
    list.do_all ( agent low.extend )
    --I can't get these to work
    list.do_if ( agent low.extend, agent piv > ? )
    list.do_if ( agent low.extend, agent piv.is_greater_equal (?) )
    list.do_if ( agent low.extend, agent piv.is_greater_equal )
    list.do_if ( agent low.extend, agent (v:INTEGER):BOOLEAN do Result := v<piv end )

我知道为什么最后一个不起作用(piv 在外部范围内),但不知道如何修复。不知道为什么其他的不行


版本 = EiffelStudio 19.5(19.05.10.3187 GPL 版 - linux-x86-64)

错误消息说:

  1. 语法无效。
  2. 实现约束:代理目标不能是基本类型。
  3. 同上
  4. 未知标识符 piv

解释:

  1. 表达式被解释为 (agent piv) < ?,这不是有效的语法。 (另一种解释 agent (piv < ?) 也是无效的:代理可以基于特征或内联,它们不能基于任意表达式。)

  2. 语言允许这样的构造,但是编译器还不支持。将来可能会提供合适的实现,并且代码可以无错误地编译。目前需要使用其他东西。

  3. 同上

  4. 内联代理不捕获周围的局部变量。如果某些本地 variables/arguments/Result 的值需要在内联代理中使用,则需要通过内联代理的显式参数传递它们。

所以,最后一个版本可以通过添加一个封闭的代理参数来修复:

agent (v, limit: INTEGER): BOOLEAN do Result := v < limit end (?, piv)

另一种方法是使用循环而不是 do_if,尽管它的声明性稍差一些:

across list as x loop if x.item < piv then low.extend (x.item) end end