Swift 编译器挂起!这是一个错误吗?

Ale*_*xey 4 xcode swift ios8

有一次,当我正在开发 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")
Run Code Online (Sandbox Code Playgroud)

在我的机器上,忙碌指示灯一直旋转,并且没有消息。我在 Xcode 6.1 (6A1052c) 和 Xcode 6.2-beta (6C86e) 上尝试过此操作。

这看起来像 Swift 编译器中的错误吗?或者我的代码有问题?

更新:

有几个人注意到我忘记了返回类型getAllowedFood函数的返回类型。然而,仅此修复并不能解决问题。编译器仍然挂起。

评论中建议了一种解决方法:

斯威夫特似乎无法解释你的字典。为字典提供显式类型来“帮助”编译器通常是个好主意。

以下添加“解除冻结”编译器:

var allowedFood: [FastingType: [String]]
Run Code Online (Sandbox Code Playgroud)

vac*_*ama 6

是的,这可以被视为编译器错误。编译器无法确定字典中键的类型。通过为字典提供显式类型或确保第一个值完全用 指定,可以消除无限循环行为FastingType.NoFast

尝试这个:

enum FastingType: Int {
    case NoFast=0, Vegetarian, FishAllowed, FastFree, Cheesefare
}

class Fasting
{
    var allowedFood:[FastingType: [String]] = [
        .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]!
    }
}
Run Code Online (Sandbox Code Playgroud)

变化:

  1. 给出allowedFood类型,[FastingType: [String]]以便它可以解释您的枚举值。
  2. 给出了getAllowedFood()一个返回类型。
  3. 解开字典查找的包装,因为它们总是返回选项。

或者,如果您的字典不详尽,您可能需要getAllowedFood()选择哪个更安全。return allowedFood[type] ?? []