【问题标题】:Swift: How to catch exception when parsing a numeric string?Swift:解析数字字符串时如何捕获异常?
【发布时间】:2017-10-21 17:57:08
【问题描述】:

在 C# 或 Java 中,通常解析数字字符串会引发格式异常。但是,下面的代码没有捕捉到错误。怎么了?

func getInt(_ data:String)->Int
{
    do
    {
        return try Int(data)!
    }
    catch
    {
        return -1;
    }
}

var a = "x123"
var b:Int = getInt(a)
print("Result: " + b)

【问题讨论】:

  • ! == 强制解包 == "我希望如果值为 nil 则程序崩溃"
  • “以下代码未捕获错误” 它还会产生两个编译器警告,强烈建议您做错了什么。奇怪的是,考虑到异常在其他地方的使用方式,这个初始化程序没有抛出。
  • 为什么你希望-1 指示解析失败,而nil 正是这样做的,没有被误解为的可能性"-1"的(成功)解析?
  • 正如我在另一条评论中所写,该方法不是真正的方法。在真实方法中,有效值永远不会是负数。

标签: swift exception


【解决方案1】:

你的方法是完全错误的。 Int 初始化器返回一个可选的 Int,所以这里是你如何使用它:

if let converted = Int (data) {
    // Yes, it was converted
} else {
    // No, conversion failed. 
}

或者

guard let converted = Int (data) else {
    // Conversion failed
    return
}

// Continue using "converted". 

try 不会捕获任何异常,因为不会抛出异常。 Int (data) 返回一个可选的 Int,即 Int 或 nil。它从不抛出。没有例外可以捕获。拥有一个仅执行 Int() 功能的函数 getInt 只会增加完全不需要的复杂性。创建一个抛出异常的函数 getInt 更糟糕。

【讨论】:

  • 该方法仅用于说明目的。真正的方法做更多的事情并返回一个 int。我在 Playground 中尝试了该示例代码,它显示了一个红色弹出窗口,在转换行出现了某种不好的异常,所以我认为它抛出了异常,就像 C# 等其他语言一样。我点击了 Int() 文档,但它显示了整个 int 类,所以我无法轻易弄清楚它抛出了哪些异常。
  • Apple 展示了如何创建一个抛出 developer.apple.com/documentation/swift/error 的 Int 初始化程序,这太糟糕了
【解决方案2】:

不要显式打开 Int(data)!,而是使用返回的 nil 对您有利:

func getInt(_ data: String) -> Int {
    return Int(data) ?? -1
}

顺便说一句,在更宏大的方案中,存在可选值,因此您不必使用诸如 -1 之类的“幻数”来表示缺失值。如果可能,重写调用此方法的代码,以便在无法解析字符串时接受nil 值。

【讨论】:

    【解决方案3】:

    在 Swift 中,只有可以throw 的方法可以catchInt 初始化器不 throw

    Swift 模式是可选的

    func getInt(_ data:String) -> Int?
    {
        return Int(data)
    }
    
    let a = "x123"
    if let b = getInt(a) {
        print("Result: \(b)")
    } else {
        print("No result")
    }
    

    或者您可以返回一个非可选的并使用 nil 合并运算符处理可选的 错误

    func getInt(_ data:String) -> Int
    {
        return Int(data) ?? -1
    }
    
    let a = "x123"
    let b = getInt(a)
    print("Result: \(b)")
    

    或者让你的方法can throw

    enum MyError : Error {
       case conversionError
    }
    
    func getInt(_ data:String) throws -> Int
    {
        guard let result = Int(data) else { throw MyError.conversionError }
        return result
    
    }
    
    let a = "x123"
    do { 
        let b = try getInt(a)
        print("Result: \(b)")
    } catch MyError.conversionError {
        print("Could not convert the string '\(a)' to integer")
    } 
    

    请阅读Swift Language Guide中关于Optionals的部分

    【讨论】:

    • 他也可以让他的方法返回一个非可选的来抛出错误而不是返回-1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多