我正在编写一些代码并犯了一个错误,该错误简化为:
func f() -> Int {
for _ in [1,2,3] {
return 1
}
}
编译器向我显示一个错误,指出f
缺少回报,这让我意识到我的错误。我忘记在周围放置一个 if 语句return
!
但后来我意识到编译器实际上在撒谎!该函数将always返回一个值。或者会吗?有什么情况下for循环不会循环吗?
我问这个是因为其他同义反复结构编译得很好:
if 1 < 2 {
return 1
}
while true {
return 1
}
而且我也明白编译器无法评估every编译时表达式以查看它们是否是同义反复。我知道属性访问和方法调用通常不会在编译时进行评估,因此预计不会编译:
if "".isEmpty {
return 1
}
但一般来说文字是可以的,对吧?毕竟,编译器必须评估文字[1,2,3]
将其翻译为机器代码,表示“用 1, 2, 3 创建一个数组”。
那么为什么它不够聪明,无法弄清楚 for 循环呢? for 循环在某些罕见情况下会不会运行吗?
虽然对于人类来说,看到循环总是重复三次是微不足道的,因为列表文字是具有三个元素的常量,但对于语义分析级别的编译器来说,这是一个不平凡的事情。
在语义分析期间,编译器将评估“通用列表文字”([1,2,3]
) 并确定它是类型的表达式Array<Int>
。但是现在,当然,这是一个常量或该数组包含三个元素的信息丢失了。
语义分析通常使用程序员正在使用的相同(或非常相似)的类型系统来执行。由于与成本相比,将数组中的元素数量附加到类型(元素数量通常在编译时未知)几乎没有什么好处,因此通常不会这样做。另一方面,不断折叠(if 1 < 2 {
)更容易实现并且更频繁地发生。
虽然在较低级别上,编译器可能会展开此循环并使用常量值,但这种情况发生得很晚 - 在 Swift 中,在生成 Swift 中间语言表示之后 - 并且可能仅在代码生成期间 - 在 SIL 被发送到 LLVM IR 之后当 LLVM 优化运行时。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)