简体   繁体   English

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

[英]Swift compiler hangs! Is it a bug?

At one point, while I was working on a Swift project, the Xcode got stuck with "Compiling Swift source" message in the status bar.有一次,当我在处理 Swift 项目时,Xcode 卡在状态栏中的“正在编译 Swift 源代码”消息中。 The compilation did not finish no matter how long I waited.不管我等了多久,编译都没有完成。 I rolled back my recent changes, and soon realized that what confuses the compiler is a very simple enum construct.我回滚了我最近的更改,很快意识到混淆编译器的是一个非常简单的枚举结构。 Below is a Playground example that illustrates the problem.下面是一个说明问题的 Playground 示例。

Create a new Playground and paste this code.创建一个新的 Playground 并粘贴此代码。 Do you see any output?你看到任何输出了吗?

// 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")

On my machine the busy indicator keeps spinning forever, and there are no messages.在我的机器上,忙指示器一直在旋转,并且没有消息。 I tried this on both Xcode 6.1 (6A1052c) and Xcode 6.2-beta (6C86e).我在 Xcode 6.1 (6A1052c) 和 Xcode 6.2-beta (6C86e) 上都试过了。

Does this look like a bug in Swift compiler?这看起来像 Swift 编译器中的错误吗? Or there is some problem in my code?还是我的代码有问题?

UPDATE:更新:

Several people noticed that I forgot return type in getAllowedFood function.有几个人注意到我忘记了getAllowedFood函数中的返回类型。 This fix alone, however, does not solve the problem.但是,仅此修复程序并不能解决问题。 The compiler still hangs.编译器仍然挂起。

A workaround was suggested in comments:评论中提出了一种解决方法:

Swift seems to have trouble interpreting your dictionary. Swift 似乎无法解释您的字典。 It's usually a good idea to give dictionaries an explicit type to "help out" the compiler.为字典提供显式类型以“帮助”编译器通常是个好主意。

The following addition "un-freezes" the compiler:以下添加“解冻”编译器:

var allowedFood: [FastingType: [String]]

Yes, this can be considered a compiler bug.是的,这可以被视为编译器错误。 The compiler is having trouble figuring out the type of the key in your dictionary.编译器无法确定字典中键的类型。 The infinite looping behavior can be eliminated by giving the dictionary an explicit type or making sure the first value is fully specified with FastingType.NoFast .可以通过为字典提供显式类型或确保第一个值完全由FastingType.NoFast指定来消除无限循环行为。

Try this:尝试这个:

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]!
    }
}

Changes:变化:

  1. Gave allowedFood the type [FastingType: [String]] so that it could interpret your enum values.allowedFood类型[FastingType: [String]]以便它可以解释您的枚举值。
  2. Gave getAllowedFood() a return type.getAllowedFood()一个返回类型。
  3. Unwrapped the dictionary lookup because they always return optionals.展开字典查找,因为它们总是返回可选项。

Alternatively, you could have getAllowedFood() to return allowedFood[type] ?? []或者,您可以让getAllowedFood() return allowedFood[type] ?? [] return allowedFood[type] ?? [] which would be safer if your dictionary is not exhaustive. return allowedFood[type] ?? []如果您的字典不是详尽无遗,这会更安全。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM