Swift编译器在switch语句中崩溃,需要解决方法

时间:2015-04-28 20:28:12

标签: swift generics enums

我的代码基本上看起来像这样,虽然我不确定这个提取的版本是否完全重现了编译器的崩溃:

enum Response<T> {
    case Success(T)
    case Failure(String)
}

struct ResponseData {
    let someData = "some data"
}

func evaluate() {
    let response = Response.Success(ResponseData())

    switch response {
    case let .Success(data):
        println("Got response with \(data)")
    case let .Failure(reason):
        println("Got failure: \(reason)")
    default: ()
    }
}

Xcode编辑器没有检测到任何问题,但是当我构建时,编译器崩溃时出现此错误:

Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1

当我评论.Success案例时,我可以建立得很好。我猜Swift编译器不喜欢泛型作为枚举的关联值。但是,该模式对我来说非常有用,它使代码更具可读性。知道如何解决这个问题吗?据我所知,除了switch语句之外,没有办法访问相关的值。

我还应该提一下,我找到the question here,但未能充分利用所提出的解决方案。

编辑实际上以下内容已经引发了一个seg-fault:

enum Response<T> {
    case Success(T)
    case Failure(String)
}

struct ResponseData {
    let someData = "some data"
}

func evaluate() {
    let response = Response.Success(ResponseData())
}
  

未实现的IR生成功能具有非固定的多载荷枚举布局   枚举回复{

2 个答案:

答案 0 :(得分:1)

归功于解决方案真的适用于上述评论的所有人。

问题似乎是Swift编译器想知道枚举在内存中的确切大小。泛型使得这是不可能的,因此编译器行为不正确。

我使用的解决方案取自Rob Rix的库,该库用于将通用设备打包成另一种类型。请注意,它必须是一个类,因为引用具有已知大小,但具有泛型的结构不具有。

@autoclosure解决方案似乎也很有趣,但它不适用于最新版本的Xcode。这是设计的;据我所知,开发人员不希望每次评估枚举时都会运行闭包。

谢谢大家!

答案 1 :(得分:1)

看起来你只能使用从NSObject继承的对象

喜欢这个

enum Result<T: NSObject>: Printable {
    case Success(T)
    case Error(NSError)

    var description: String {
        switch self{
        case .Success(let obj):
            return obj.description
        case .Error(let error):
            return error.description
    }
}

然后

let r = Result.Success("Xcode")

r.description

UPD: 你可以做这样的事情

@objc
protocol ResultObjectProtocol {
    var description: String { get }
}

extension NSDictionary: ResultObjectProtocol {}

enum Result<T: ResultObjectProtocol>: Printable {
    case Success(T)
    case Failure(NSError)

    var description: String {
        switch self{
        case .Success(let obj):
            return obj.description
        case .Failure(let error):
            return error.description
        }
    }
}

let r = Result.Success(["d" : 132]).description

注意:var description - 仅举例来说

UPD。 (斯威夫特4) 您可以在枚举中使用泛型类型:

enum Result<T> {
    case success(T)
    case error(Error)
}