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

swift – 全局函数序列(state:next :)和类型推断

发布时间:2020-12-14 05:47:04 所属栏目:百科 来源:网络整理
导读:背景细节 Swift进化建议SE-0094在Swift 3.0中实现,引入了全局序列函数: sequence(first:next:) sequence(state:next:) 后者声明如下 06000 并在swift/stdlib/public/core/UnfoldSequence.swift中实现.语言参考提供了以下使用它的示例(请注意缺少显式类型注
背景&细节

Swift进化建议SE-0094在Swift 3.0中实现,引入了全局序列函数:

> sequence(first:next:)
> sequence(state:next:)

后者声明如下

06000

并在swift/stdlib/public/core/UnfoldSequence.swift中实现.语言参考提供了以下使用它的示例(请注意缺少显式类型注释)

06001

但是,我不能让上面的例子工作(例如使用let seq1 = 1 … 3,让seq2 = 4 … 6),但是会出现相当奇怪的错误消息

error: ambiguous reference to member ‘sequence(first:next:)

只有当我在下一个闭包中显式地键入注释可变状态参数以及它的返回类型时,上面的例子才会编译

let seq1 = 1...3
let seq2 = 4...6

for i in sequence(state: (false,seq1.makeIterator(),seq2.makeIterator()),next: { (iters: inout (Bool,ClosedRangeIterator<Int>,ClosedRangeIterator<Int>)) 
                        -> Int? in
    iters.0 = !iters.0
    return iters.0 ? iters.1.next() : iters.2.next()
}) {
    print(i)
} // 1 4 2 5 3 6

这不是我希望使用序列(state:next :)的方式,但是,因为我宁愿在即时应用程序中看到它,其中类型推断可以正常工作,避免所有的显式性.

>我们是否打算使用序列(first:next :)函数和上面的显式类型注释?由于inout参数关闭,这个函数是否有一些限制,或者我错过了什么?

这看起来像是两个问题的组合.

第一个是Swift目前没有推断出没有任何外部上下文的多行闭包的类型.然而,正如Apple开发人员Jordan Rose在SR-1570的评论中所证实的那样,这是预期的行为:

This is correct behavior: Swift does not infer parameter or return types from the bodies of multi-statement closures. But the diagnostic could be a lot better.

因此理论上,您只需要显式定义传递给sequence()的next:参数的闭包的返回类型,因为参数类型可以从外部上下文推断(即传递给state的类型:参数):

let seq1 = 1...3
let seq2 = 4...6

let combined = sequence(state: (false,next: { iters -> Int? in
    iters.0 = !iters.0
    return iters.0 ? iters.1.next() : iters.2.next()
})

(编辑:现在在Swift 3.1中编译)

但是,这仍然无法编译 – 这是由于第二个问题,编译器无法推断Swift 3中的inout闭包参数的类型(在Swift 2中不是这种情况).这是一个可疑的错误,已经提交(见SR-1976和SR-1811).

因此,正如您在问题中所述,这意味着(非常不满意)您必须显式注释您传递给下一个的完整闭包签名::

let combined = sequence(state: (false,ClosedRangeIterator<Int>)) -> Int? in
    iters.0 = !iters.0
    return iters.0 ? iters.1.next() : iters.2.next()
})

(编辑:李大同)

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

    推荐文章
      热点阅读