【问题标题】:Unwrap variable which is not optional?解包不是可选的变量?
【发布时间】:2023-04-04 20:12:01
【问题描述】:

我在一个简单的计算器应用程序中遇到了这些代码行。

func processOperation (operation: Operation) {
    if currentOperation != Operation.Empty {
        if runningNumber != "" {
            rightValStr = runningNumber
            runningNumber = ""

            if currentOperation == Operation.Multiply {
                result = "\(Double(leftValStr)! * Double(rightValStr)!)"
            } else if currentOperation == Operation.Divide {
                result = "\(Double(leftValStr)! / Double(rightValStr)!)"
            } else if currentOperation == Operation.Subtract {
                result = "\(Double(leftValStr)! - Double(rightValStr)!)"
            } else if currentOperation == Operation.Add {
                result = "\(Double(leftValStr)! + Double(rightValStr)!)"
            }

leftValStr 被声明为var leftValStr = ""

rightValStr 也被声明为var rightValStr =""

我想知道使用“!”的目的是什么在\(Double(leftValStr)! / Double(rightValStr)!) 是为了什么? 据我所知,“!”用于展开可选。这里的 leftValStr 和 rightValStr 没有声明为 Optional 那么为什么我们必须解开它们呢?

【问题讨论】:

    标签: swift optional unwrap


    【解决方案1】:

    即使leftValStrrightValStr 不是可选项,您也将强制解开Double(leftValStr)Double(rightValStr) 以及使用String 初始化Double 的结果值可以是nil

    例如,您不能使用 stackoverflow 字符串初始化 Double。

    如果您想确保这个转换结果是正确的,您可以使用if let 来避免强制展开,例如:

    if let leftValDouble = Double(leftValStr) {
        // do your code
    } else {
        // handle error
    }
    

    请记住,如果您强制解开 nil 值,您的代码将会崩溃。

    【讨论】:

    • 所以当结果可能为空时我应该使用强制展开?
    • @Frankie 不,如果结果为 nil 并强制解包,您的代码将崩溃。首先请参阅 Apple 文档中的指南,如何使用 Optional。
    • 如果您 100% 确定这些值将仅是 有效 数字 - 有条件的是,但如果您让用户粘贴一些值或任何其他情况 - 您应该检查结果使用例如if let。请记得写一些单元测试,这是一个完美的用例。
    • 如果我 100% 知道这些值将是有效数字,我可以使用 Double(leftValStr) 代替 Double(leftValStr)! 吗?我仍然不清楚何时使用强制展开。很抱歉给大家带来了困扰,我才刚开始学习 Swift 几天。
    • 别担心,这里的每个人都愿意帮助你。 :) 好的,you 确信这些值是有效的,但 compiler 不是。所有编译器都知道他得到了一些字符串,结果可能是 Double 或nil。因此,通过使用感叹号!,你会说:是的,我确定我为你提供了一个有效的字符串,所以你会给我一个 Double。但是强制展开 (!) 是有风险的,通常不是一个好的做法,因此您应该在不可为空的上下文中使用它之前检查任何可空值。
    【解决方案2】:

    您使用的 Double 初始化程序是 failable 初始化程序,即它可能会创建 Double 或返回 nil

    示例

    Double("3"),这里的“3”可以转换成Double,所以它返回一个可选的Double值,对应3。

    Double("abc"),这里的“abc”不能转换成Double,所以本例返回nil

    在您的代码中,您使用的是 Double(""),它也无法转换为 Double,因此它返回 nil

    现在,当你force unwrap 一个nil 值时,会导致运行时异常。

    因此,Double(leftValStr)! 导致运行时异常。

    尝试使用!访问不存在的可选值会触发 运行时错误。始终确保可选项包含非零 使用前的价值!强制解包它的值。

    【讨论】:

    • 如果您觉得答案有用,请考虑投票。
    • 我有,但由于我的声望少于 15,所以只记录投票。对不起:(
    • 呵呵..oki..那么一切顺利..:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多