Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 具有多个闭包的泛型函数不起作用_Arrays_Swift_Generics_Closures - Fatal编程技术网

Arrays 具有多个闭包的泛型函数不起作用

Arrays 具有多个闭包的泛型函数不起作用,arrays,swift,generics,closures,Arrays,Swift,Generics,Closures,我想创建一个泛型函数,它可以将数组聚合为一种类型。我将用一个愚蠢但简单的例子来解释 假设我得到了这个代码: class Entity { var someElement: Int } 现在,我已经在数组扩展中编写了此函数,以便可以在任何数组上使用它: /** * An aggregation function. The first closure extracts the useful data in a new object, the second one aggregates t

我想创建一个泛型函数,它可以将数组聚合为一种类型。我将用一个愚蠢但简单的例子来解释

假设我得到了这个代码:

class Entity {
    var someElement: Int
}
现在,我已经在
数组扩展中编写了此函数,以便可以在任何数组上使用它:

/**
 * An aggregation function. The first closure extracts the useful data in a new object, the second one aggregates two items of the same type in one.
 * 
 * The algorithm works from front to back
 *
 * @return the aggregated value or nil if the array is empty
 */
func aggregate<R>(translation: (T) -> R, aggregation: (R, R) -> R) -> R? {
    if count == 0 {
        return nil
    }
    if count == 1 {
        return translation(self.first!)
    }
    var calc = translation(self.first!)
    for item in 1..<count {
        calc = aggregation(calc, translation(self[item]))
    }
    return calc
}
但我得到了这个疯狂的错误。我得到了这个疯狂的错误。我得到了这个疯狂的错误:<代码>不能转换表达的类型((((((((((($T5)T5)->((((((((($T5)5)->(((((($T5)5)->((((((((($T5)5))->((((((((((((((((($T5)5))->)T5)->(((((((($T5)T5)T4)))->((((((((((($T5)T4)T4)T4)T4)T4)T4))))))->((((((((((((((($T4)T4)T4)T4)T4)T4)T4)T4)T4)))))))))))->$T6,$T8)->$T6)->$T6)->


到底发生了什么事?在Xcode中,当我检查
项的类型时,它是
,因此它甚至不能编译到那里。是否需要指定函数调用中的R?

看起来斯威夫特在推断第一个闭包的类型时遇到了问题。如果更新对聚合的调用以显式提供类型:

array.aggregate(
    {
        (item: Entity)->Int in
        return item.someElement
    }, aggregation: {
        (item1, item2) in
        return item1 + item2
    }
)
它编译/运行正常

有趣的是,如果不使用显式返回,则推理可以正常工作:

array.aggregate(
    {
        item in
         item.someElement
    }, aggregation: {
        (item1, item2) in
        return item1 + item2
})
array.aggregate({$0.someElement},+)
也可以正常工作)

另外,如果您对替代方案感兴趣,您可以重写
aggregate
,如下所示:

extension Array {
    func aggregate<R>(translation: T -> R, aggregation: (R, R) -> R) -> R? {

        return self.first.map { fst in
            dropFirst(self).reduce(translation(fst)) { aggregation($0, translation($1)) }
        }
    }
}
扩展数组{
函数聚合(翻译:T->R,聚合:(R,R)->R)->R{
返回self.first.map{fst in
dropFirst(self).reduce(translation(fst)){aggregation($0,translation($1))}
}
}
}

是的,我想这可能就是问题所在。谢谢你的解决方案!编辑:我想这只是测试版,我希望在下一个版本中可以修复。我将对此提交一份错误报告。此外,使用map函数也是一个好主意,我将测试两种不同的方法的速度,并使用最快的方法。我已经在一个
for
循环中运行了一个多达10K个元素的测试,每次添加一个元素。结果以csv格式打印并可用(数据以纳秒为单位)。我创造了。伙计,在我2011年初的基础MBP上,创建这个图表花了很多时间。我想是时候升级了。TL;DR:您的mapreduce方式的速度大约是2或3倍。
extension Array {
    func aggregate<R>(translation: T -> R, aggregation: (R, R) -> R) -> R? {

        return self.first.map { fst in
            dropFirst(self).reduce(translation(fst)) { aggregation($0, translation($1)) }
        }
    }
}