将运算符作为函数传递

Passing an operator as a function

我是 Groovy 的新手。我想将运算符作为函数传递。

而不是:

nums.inject(0) { acc, el -> acc * el }

我想做这样的事情:

nums.inject(0) {*}

在 F# 中,这是可能的。 Groovy 是否提供相同的语法糖?

let product = List.reduce (*) nums 0

我不这么认为。但是,您可以通过一些元编程来接近。

/* 
 * Creates the method Collection.reduce(Object, Closure).
 * Unlike Collection.inject(Object, Closure), this method
 * expects a closure with a single argument: the
 * current element in the collection. The closure is
 * re-created to run with the accumulated value as the
 * owner and then called with the current element as the argument.
 */
Collection.metaClass.reduce = { Object initial, Closure closure ->
    delegate.inject(initial) { acc, obj ->
        closure.rehydrate(acc, acc, acc)(obj)
    }
}

def nums = [1, 2, 3]

/*
 * Number.&multiply returns the Number.multiply(Number) method
 * as a Closure.
 */
def result = nums.reduce(1, Number.&multiply) 

assert result == 6

为了让您更好地了解 reduce(Object, Closure) 方法的工作原理,还有另一种使用方法:

nums.reduce(1) { num -> multiply(num) }

闭包的唯一参数是当前元素。因为所有方法调用和 属性 访问都委托给累加器,所以 multiply(Number) 方法针对累加器执行:acc.multiply(num).

运算符不允许传递,但 functions/closures 可以,所以或多或少等价

def product = nums.inject(1, Math.&multiplyExact)

inject 接受两个参数,一个对象和一个闭包。您的示例定义了自己的闭包,但可以使用 method pointer operator (.&)

将方法引用为闭包

放置一个 文字 闭包,括号外的 { } 是一个小语法糖,可以为方法调用的最后一个参数的任何闭包完成。