是否有任何情况下“ [1,2,3]中的_都不会循环”?

我在编写一些代码,但犯了一个错误,简化为:

func f() -> Int {
    for _ in [1,2,3] {
        return 1
    }
}

And the compiler shows me an error saying that f is missing an return, which caused me to realise my mistake. I forgot to put an if statement around the return!

但是后来我意识到编译器实际上是在撒谎!该函数将始终返回一个值。还是会?有什么情况下for循环不会循环?

我之所以这样问是因为其他重言式的构造都可以编译:

if 1 < 2 {
    return 1
}

while true {
    return 1
}

而且我也明白,编译器无法在编译时评估每个表达式以查看它们是否是重言式的。我知道属性访问和方法调用通常不会在编译时进行评估,因此不希望编译该代码:

if "".isEmpty {
    return 1
}

But generally literals are ok, right? After all, the compiler has to evaluate the literal [1,2,3] to translate it into machine code that says "create an array with 1, 2, 3".

那么为什么找出for循环还不够聪明呢?在某些罕见情况下,for循环不会运行吗?

评论
在景龙
在景龙

虽然对于人类来说,看到循环将始终重复三次是很简单的,但是由于列表文字是具有三个元素的常量,对于编译器而言,在语义分析级别上看到这并非易事。

During semantic analysis, the compiler will evaluate a generic list literal ([1,2,3]) and determine that it is an expression of type Array<Int>. But now, of course, the information that this is a constant or that this array contains three elements is lost.

语义分析通常使用程序员使用的相同(或非常相似)类型的系统执行。由于将数组中元素的数量附加到类型上(元素的数量通常是未知的)几乎没有好处,因此通常不会这样做。

虽然在较低级别上,编译器可能会展开此循环并使用常量值,但这种情况发生得很晚–在生成Swift中间语言表示形式后的Swift中–可能仅在代码生成期间–在将SIL发出到LLVM IR和运行LLVM优化时。

点赞
评论