为什么 Swift 编译器不能推断这个闭包的类型? [英] Why can't the Swift compiler infer this closure's type?

查看:37
本文介绍了为什么 Swift 编译器不能推断这个闭包的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在编写代码来区分我的应用程序的多个版本:

So I was writing code to differentiate multiple versions of my app:

static var jsonURLNL =  {
    if ProcessInfo.processInfo.environment["CONSUMER"] != nil {
        return URL(string: "consumerURL")!
    }
    return URL(string: "professionalURL")!
}()

但是我得到了一个编译器错误:

But I got a compiler error:

无法推断复杂的闭包返回类型;添加显式类型以消除歧义

Unable to infer complex closure return type; add explicit type to disambiguate

为什么 Swift 编译器不知道这会返回一个 URL?我认为在这种情况下这是相当明显的.

Why can't the Swift compiler know that this will return a URL? I think it is fairly obvious in this case.

我提出这个问题的目的不是批评 Xcode 或 Swift,而是增加我对编译器如何推断 Swift 类型的知识.

My goal with this question is not to give critique on Xcode or Swift, it is to increase my knowledge of how the compiler infers types in Swift.

推荐答案

闭包的返回类型只有在闭包由一个单个表达式组成,例如:

The return type of a closure is only inferred automatically if the closure consists of a single expression, for example:

static var jsonURLNL =  { return URL(string: "professionalURL")! }()

或者如果可以从调用上下文推断类型:

static var jsonURLNL: URL =  {
    if ProcessInfo.processInfo.environment["CONSUMER"] != nil {
        return URL(string: "consumerURL")!
    }
    return URL(string: "professionalURL")!
}()

static var jsonURLNL = {
    if ProcessInfo.processInfo.environment["CONSUMER"] != nil {
        return URL(string: "consumerURL")!
    }
    return URL(string: "professionalURL")!
}() as URL

简化示例:这个单表达式闭包编译:

Simplified examples: This single-expression closure compiles:

let cl1 = { return 42 }

但是这个多表达式闭包没有:

but this multi-expression closure doesn't:

let cl2 = { print("Hello"); return 42 }
// error: unable to infer complex closure return type; add explicit type to disambiguate

以下几行可以编译,因为类型是从上下文中推断出来的:

The following lines compile because the type is inferred from the context:

let cl3 = { print("Hello"); return 42 } as () -> Int

let y1: Int = { print("Hello"); return 42 }()

let y2 = { print("Hello"); return 42 }() as Int

<小时>

另见 Jordan Rose 的引用 in此邮件列表讨论:

Swift 的类型推断目前是面向语句的,因此没有简单的方法来进行 [多语句闭包] 推断.这至少部分是编译时的问题:Swift 的类型系统允许比 Haskell 或 OCaml 多得多的可能转换,因此解决整个多语句函数的类型不是一个小问题,可能不是一个容易处理的问题.

Swift's type inference is currently statement-oriented, so there's no easy way to do [multiple-statement closure] inference. This is at least partly a compilation-time concern: Swift's type system allows many more possible conversions than, say, Haskell or OCaml, so solving the types for an entire multi-statement function is not a trivial problem, possibly not a tractable problem.

SR-1570 错误报告.

(链接和引用均从 flatMap API 契约如何将可选输入转换为非可选结果?).

(Both links and the quote are copied from How flatMap API contract transforms Optional input to Non Optional result?).

这篇关于为什么 Swift 编译器不能推断这个闭包的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆