【发布时间】:2015-01-31 10:17:40
【问题描述】:
有一次,当我在处理一个 Swift 项目时,Xcode 卡住了状态栏中的“正在编译 Swift 源代码”消息。不管我等了多久,编译都没有完成。我回滚了我最近的更改,并很快意识到让编译器感到困惑的是一个非常简单的枚举构造。下面是一个说明问题的 Playground 示例。
创建一个新的 Playground 并粘贴此代码。你看到任何输出了吗?
// Playground - noun: a place where people can play
import UIKit
enum FastingType: Int {
case NoFast=0, Vegetarian, FishAllowed, FastFree, Cheesefare
}
class Fasting
{
var allowedFood = [
.NoFast: ["meat", "fish", "milk", "egg", "cupcake"],
.Vegetarian: ["vegetables", "bread", "nuts"],
.FishAllowed: ["fish", "vegetables", "bread", "nuts"],
.FastFree: ["cupcake", "meat", "fish", "cheese"],
.Cheesefare: ["cheese", "cupcake", "milk", "egg"]
]
func getAllowedFood(type: FastingType) -> [String] {
return allowedFood[type]
}
}
var fasting = Fasting()
println(fasting.getAllowedFood(.Vegetarian))
println("Hello world")
在我的机器上,忙碌指示灯一直在旋转,并且没有消息。我在 Xcode 6.1 (6A1052c) 和 Xcode 6.2-beta (6C86e) 上都试过这个。
这看起来像 Swift 编译器中的错误吗?还是我的代码有问题?
更新:
一些人注意到我忘记了getAllowedFood 函数中的返回类型。但是,仅此修复程序并不能解决问题。编译器仍然挂起。
在 cmets 中提出了一种解决方法:
Swift 似乎无法解释您的字典。给字典一个明确的类型来“帮助”编译器通常是个好主意。
以下添加“取消冻结”编译器:
var allowedFood: [FastingType: [String]]
【问题讨论】:
-
永远不要在操场上测试。 (我知道这就是 Apple 所说的,但不要这样做。)如果您只是在真正的应用程序而不是操场上执行所有这些操作,编译器会为您提供明确的错误消息。
-
哦,还有一条建议。当然,Swift 或 Cocoa 中可能存在错误,但除非你首先了解当出现问题时,是 你 做错了,否则你不会学习编程。
-
如果我做错了什么,编译器应该显示错误信息,而不是无限循环!
-
Matt 的建议是务实的,但是是的,编译应该本质上是确定性的,并且永远不要无限循环,即使在操场上也是如此。