在Swift

时间:2016-05-26 23:07:54

标签: ios swift exception try-catch throw

我正在尝试学习Swift,并想知道Apple对Apple实验的{strong>错误处理部分中提供的实验的预期答案如下所示GuidedTour操场如下;

  

实验:添加代码以在do块中抛出错误。你需要抛出什么样的错误,以便错误由第一个catch块处理?那第二和第三块呢?

enum PrinterError: ErrorType {
    case OutOfPaper
    case NoToner
    case OnFire
}

func sendToPrinter(printerName: String) throws -> String {
    if printerName == "Never Has Toner" {
        throw PrinterError.NoToner
    }
    return "Job sent"
}

do {
    let printerResponse = try sendToPrinter("Gutenberg")
    print(printerResponse)
} catch PrinterError.OnFire {
    print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
    print("Printer error: \(printerError).")
} catch {
    print(error)
}

以下是我对这个实验中提出的问题的回答,它们似乎都有效......

  

您需要抛出什么样的错误,以便错误由第一个catch块处理?

添加 throw PrinterError.OnFire ,如下所示;

do {
    throw PrinterError.OnFire
    let printerResponse = try sendToPrinter("Gutenberg")
    print(printerResponse)
} catch PrinterError.OnFire {
    print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
    print("Printer error: \(printerError).")
} catch {
    print(error)
}
  

第二次......

" Never Have Toner" 发送至 sendToPrinter

do {
    let printerResponse = try sendToPrinter("Never Has Toner")
    print(printerResponse)
} catch PrinterError.OnFire {
    print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
    print("Printer error: \(printerError).")
} catch {
    print(error)
}
  

......和第三块?

我可以触发第三个区块的唯一方法 - 在我看来是这个案例中的预期答案 - 是创建一个符合 ErrorType 的不同枚举并投掷它,如下所示;

enum anotherEnum: ErrorType {
    case someCase
}

do {
    throw anotherEnum.someCase
    let printerResponse = try sendToPrinter("Gutenberg")
    print(printerResponse)
} catch PrinterError.OnFire {
    print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
    print("Printer error: \(printerError).")
} catch {
    print(error)
}

然而,由于此实验的第一句开头是" 添加代码以在do块中抛出错误 ",我想知道如果在阻止中留下我应该发现的其他预期答案。

我问,因为我不想错过我应该发现的其他内容。从Apple的角度来看,您认为这些答案是否有效?

谢谢!

1 个答案:

答案 0 :(得分:1)

第三种情况的一个更实际的例子可能是在尝试向网络打印机发送内容之前检查网络是否可用:

enum NetworkError: ErrorType {
    case Unavailable
}

enum PrinterError: ErrorType {
    case OutOfPaper
    case NoToner
    case OnFire
}

func sendToPrinter(printerName: String) throws -> String {
    if printerName == "Never Has Toner" {
        throw PrinterError.NoToner
    }
    return "Job sent"
}

var networkAvailable = false     // some other process will update this when the network is available

然后你可以这样做:

do {
    if !networkAvailable {
        throw NetworkError.Unavailable
    }

    let printerResponse = try sendToPrinter("Gutenberg")
    print(printerResponse)
} catch PrinterError.OnFire {
    print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
    print("Printer error: \(printerError).")
} catch {
    print(error)
}

这将导致第三个catch块被捕获。

或者更现实,可可的例子可能是:

do {
    let documents = try NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
    let fileURL = documents.URLByAppendingPathComponent("document.txt")
    let contents = try String(contentsOfURL: fileURL)

    let printerResponse = try sendToPrinter(contents)
    print(printerResponse)
} catch PrinterError.OnFire {
    print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
    print("Printer error: \(printerError).")
} catch {
    print(error)
}

请注意,这并非实际上手动抛出错误,而是依赖于URLForDirectoryString(contentsOfURL:)引发的错误。但是,如果在document.txt文件夹中找不到Documents,则String(contentsOfURL:)会抛出错误,该错误会被第三个catch阻止。