Swift compiler hangs! Is it a bug?

*爱你&永不变心* 提交于 2019-12-20 02:58:05

问题


At one point, while I was working on a Swift project, the Xcode got stuck with "Compiling Swift source" message in the status bar. 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.

Create a new Playground and paste this code. 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).

Does this look like a bug in Swift compiler? Or there is some problem in my code?

UPDATE:

Several people noticed that I forgot return type in getAllowedFood function. 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. 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]]

回答1:


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.

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.
  2. Gave getAllowedFood() a return type.
  3. Unwrapped the dictionary lookup because they always return optionals.

Alternatively, you could have getAllowedFood() to return allowedFood[type] ?? [] which would be safer if your dictionary is not exhaustive.



来源:https://stackoverflow.com/questions/27261775/swift-compiler-hangs-is-it-a-bug

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!