
我有一个遵循这种模式的递归函数:
func recurseArray(arr: [Int]) -> [Int] { guard let first = arr.first else { return [] } let rest = recurseArray(Array(dropFirst(arr))) let next = rest.first ?? 0 return [first + next] + rest} 显然,真正的代码比将每个数字添加到下一个数字要多得多.
注意对Array的调用(dropFirst(seq)).需要转换为数组,因为dropFirst实际上返回一个ArraySlice,而ArraySlice不是Sliceable,所以我无法将它传递给我的函数.
我不确定编译器在这里能做什么样的优化,但在我看来,从SubSlice创建一个新的数组是不必要的.这个问题有方法解决吗?
此外,我真正想做的是创建一个可以采用任何Sliceable类型的函数版本:
func recurseSeq<T: Sliceable where T.Generator.Element == Int>(List: T) -> [Int] { guard let first = List.first else { return [] } let rest = recurseSeq(dropFirst(List)) // <- Error - cannot invoke with argument type T.SubSlice let next = rest.first ?? 0 return [first + next] + rest} 这次我没有解决我有SubSlice的事实.我怎样才能实现目标?
事实证明,有一个通用的解决方案.您需要添加这些通用要求:< S : Sliceable where S.SubSlice : Sliceable,S.SubSlice.Generator.Element == S.Generator.Element,S.SubSlice.SubSlice == S.SubSlice >
对于发布的问题,这给出了:
func recurseSeq< S : Sliceable where S.SubSlice : Sliceable,S.SubSlice.Generator.Element == Int,S.SubSlice.SubSlice == S.SubSlice,S.Generator.Element == Int >(List: S) -> [Int] { guard let first = List.first else { return [] } let rest = recurseSeq(dropFirst(List)) let next = rest.first ?? 0 return [first + next] + rest} 这是任何切片上有用的通用缩减:
extension Sliceable where SubSlice : Sliceable,SubSlice.Generator.Element == Generator.Element,SubSlice.SubSlice == SubSlice { func recReduce(combine: (Generator.Element,Generator.Element) -> Generator.Element) -> Generator.Element? { return self.first.map { head in dropFirst(self) .recReduce(combine) .map {combine(head,)} ?? head } } } [1,2,3].recReduce(+) // 6 我不能相信这一点,Apple开发论坛上的解决方案是posted.
令人遗憾的是,通用要求如此涉及到这样一个基本 *** 作 – 它几乎不直观!但我很高兴有一个解决方案……
总结以上是内存溢出为你收集整理的Swift Sliceable上的递归全部内容,希望文章能够帮你解决Swift Sliceable上的递归所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)