首页 > 解决方案 > 如何解决由于强制展开导致的致命意外 nil 错误

问题描述

我刚刚开始学习 swift 的基础知识,并且正在使用 swiftui 制作一个计算器来掌握它。但是,在尝试强制解包变量时,我不断收到错误消息,即发现 nil 值。我知道使用强制展开不是安全的做法,所以我尝试用 if let 语句替换它,但那些只会让我的计算结果变为 0,即它永远不会进入 if let 语句。我的代码逻辑在图片中,任何帮助将不胜感激。

由于意外 nil 导致应用程序崩溃的代码

import SwiftUI

struct ContentView: View {
    @State private var firstnumber = 0
    @State private var secondnumber = 0
    @State private var operand = ""
    @State private var calctext = "0"
    @State private var isTyping = false

    var body: some View {
        ZStack { Color.black
            .edgesIgnoringSafeArea(.all)
            VStack(){
            TextField("0", text: $calctext)
                .padding(EdgeInsets(top: 150, leading: 20, bottom: 20, trailing: 20))
                .border(Color.gray, width: 2)
                .multilineTextAlignment(.trailing)
                .foregroundColor(Color.white)
                .font(.largeTitle)



            HStack{
                createbutton("AC")
                .buttonStyle(numberdesign1())
                Spacer()
                createbutton("+/-")
                .buttonStyle(numberdesign1())
                Spacer()
                createbutton(" % ")
                .buttonStyle(numberdesign1())
                Spacer()
                Button(action: {
                    self.operandclick("÷")
                }) {
                Text(" ÷ ")
                }
                .buttonStyle(buttondesign())
                .cornerRadius(15.0)
            }.padding()

            HStack{
                createbutton(" 9 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 8 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 7 ")
                .buttonStyle(numberdesign())
                Spacer()
                Button(action: {
                    self.operandclick("×")
                }) {
                Text(" × ")
                }
                .buttonStyle(buttondesign())
                .cornerRadius(15.0)
            }.padding()

            HStack{
                createbutton(" 6 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 5 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 4 ")
                .buttonStyle(numberdesign())
                Spacer()
                Button(action: {
                    self.operandclick("-")
                }) {
                Text(" - ")
                }
                .buttonStyle(buttondesign())
                .cornerRadius(15.0)
            }.padding()

            HStack{
                createbutton(" 3 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 2 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 1 ")
                .buttonStyle(numberdesign())
                Spacer()
                Button(action: {
                    self.operandclick("+")
                }) {
                Text(" + ")
                }
                .buttonStyle(buttondesign())
                .cornerRadius(15.0)

            }.padding()

            HStack{
                Button(action: {
                    self.digitTapped("0")

                }) {
                    Text(" 0                           ")
                }
                .foregroundColor(Color.white)
                .padding(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
                .background(Color.gray)
                .border(Color.gray, width: 1)
                .cornerRadius(40.0)
                Spacer()
                createbutton("  .  ")
                .buttonStyle(numberdesign())
                Spacer()
                Button(action: {
                    self.calculate()
                }) {
                Text(" = ")
                }
                .buttonStyle(buttondesign())
                .cornerRadius(15.0)

            }.padding()



            }
            .aspectRatio(contentMode: .fill)

        }
    }

    private func createbutton(_ number: String) -> Button<Text> {
        return Button(action: {
            self.digitTapped(number)
        }) {
            (Text(number))
        }
    }

    private func digitTapped(_ number: String) -> Void {
        if isTyping {
            calctext += number
        } else {
            calctext = number
            isTyping = true
        }
    }

    private func operandclick(_ operand: String) {
        isTyping = false
//        if Int(calctext) != nil {
        firstnumber = Int(calctext)!
//        }
        
        self.operand = operand
        calctext = operand
    }

    private func calculate() {
        isTyping = false
        var result = 0
//        if Int(calctext) != nil {
        secondnumber = Int(calctext)!
//        }
        

        if operand == "+" {
            result = firstnumber + secondnumber
            print (result, firstnumber, secondnumber)
        } else if operand == "-" {
            result = firstnumber - secondnumber
        } else if operand == "÷" {
            result = firstnumber / secondnumber
        } else if operand == "×" {
            result = firstnumber * secondnumber
        }

        calctext = "\(result)"
    }
}




struct buttondesign: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(Color.white)
            .padding()
            .background(LinearGradient(gradient: Gradient(colors: [Color("DarkGreen"),Color("LightGreen")]), startPoint: .leading, endPoint: .trailing))
        .clipShape(Circle())
    }
}

struct numberdesign: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
        .foregroundColor(Color.white)
            .padding(.all)
        .background(Color.gray)
        .border(Color.gray, width: 1)
            .clipShape(Circle().scale(1))

    }
}

struct numberdesign1: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
        .foregroundColor(Color.black)
        .padding(.all)
        .background(Color("LightGray"))
        .border(Color.gray, width: 1)
        .clipShape(Circle())

    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }

}

标签: swiftswiftui

解决方案


除非您确定它们不包含任何 nil 值,否则不应强制解包选项。

我建议您使用nil coalescing运算符为字符串的整数转换提供默认值

let firstNumber = Int(calcText) ?? 0

推荐阅读