我在编写一些代码,但犯了一个错误,简化为:
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 typeArray<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优化时。