异常处理 – 异常处理的Swift异常

异常处理 – 异常处理的Swift异常,第1张

概述在通过论坛和 Swift文档进行细读之后(不完全,我承认),似乎在Swift中我们鼓励编写更安全的代码,而不是try-catch机制.鉴于此,我对一个示例API有疑问,并想学习如何更安全地处理这种情况: 例如,我可以使用NSDecimalNumberHandler创建以下类: class MathWhiz { init() { let defaultBehavior: NSDec 在通过论坛和 Swift文档进行细读之后(不完全,我承认),似乎在Swift中我们鼓励编写更安全的代码,而不是try-catch机制.鉴于此,我对一个示例API有疑问,并想学习如何更安全地处理这种情况:

例如,我可以使用NSDecimalNumberHandler创建以下类:

class MathWhiz {    init() {    let defaultBehavior: NSDecimalNumberHandler =    NSDecimalNumberHandler.defaultDecimalNumberHandler()    }    func add(op1: String,op2: String) ->NSDecimalNumber {        return NSDecimalNumber.decimalNumberWithString(op1).decimalNumberByAdding(NSDecimalNumber.decimalNumberWithString(op2))    }}

如果我使用以下内容,我会得到一个数字:

let brain = MathWhiz()brain.add("1",op2: "1e127")

但是,如果我导致溢出异常,:

brain.add("1",op2: "1e128")

我会按预期崩溃程序.

所以,我的问题是,API引发异常,但我不在这里处理它们.还有其他帖子指出Swift没有异常处理,但是这个问题正在寻找一种很好的方式来处理这个问题,就像语言创建者认为应该完成的那样.
有没有一种推荐的方法来处理这个问题而不必编写我自己的代码来检查溢出,下溢,精度损失等等?我想要NSDecimalNumberHandler为我做这件事.

解决方法 如果您在Swift中设计函数(或方法),则至少有3个选项来处理错误:

选择1:返回可选类型

如果您的函数可能失败,并且这种情况经常发生,那么请考虑返回一个可选的类型变量.例如,在您的情况下,您的方法add可以返回NSDecimalNumber?而不是普通的NSDecimalNumber.在这种情况下,您的方法将检查可能出错的所有内容,并在这些情况下返回nil.溢出和下溢将返回nil,并且所有其他情况将返回NSDecimalNumber.调用者必须检查和解包可选的NSDecimalNumber,如下所示:

let brain = MathWhiz()if let sum = brain.add("1",op2: "1e127") {    println("the result was \(sum)")} else    println("something went wrong with MathWhiz add")}

选择2:返回枚举类型

如果要返回有关出错的更多信息,可以创建一个枚举类型,其中包含每个错误的值和一个嵌入答案的成功值.例如,您可以这样做:

enum MathWhizResult {    case Overflow    case Underflow    case Success(NSDecimalNumber)}

然后将定义add以返回MathWhizResult:

func add(op1: String,op2: String) -> MathWhizResult

如果出现错误,add将返回.Overflow或.Underflow.如果成功,add将返回Success(结果).调用者必须检查枚举并解压缩结果.可以使用一个开关:

switch (brain.add("1",op2: "1e128")) {case .Overflow    println("darn,it overflowed")case .Underflow    println("underflow condition happened")case .Success(let answer)    println("the result was \(answer)"}

选择3:选择不明确处理错误

在前两个选项中解压缩结果对于非常罕见的错误可能是过多的开销.您可以选择仅返回结果,并让调用者处理下溢或溢出情况的可能性.在这种情况下,他们必须在调用add之前自己检查这些条件.好处是,他们知道他们的程序永远不会导致下溢或溢出(因为他们正在处理单个数字的数字),他们没有负担解压缩结果.

我创建了一个小应用程序来演示如何使用NSDecimalNumbers执行此 *** 作.我在Xcode中创建了一个单视图应用程序.在StoryBoard的VIEwController中,我添加了3个TextFIElds( *** 作数1, *** 作数2和结果各一个)和我标记的button.

VIEwController.swift

import UIKitclass VIEwController: UIVIEwController {    @IBOutlet var operand1 : UITextFIEld!    @IBOutlet var operand2 : UITextFIEld!    @IBOutlet var result   : UITextFIEld!    var brain = MathWhiz()    overrIDe func vIEwDIDLoad() {        super.vIEwDIDLoad()        // Do any additional setup after loading the vIEw,typically from a nib.    }    overrIDe func dIDReceiveMemoryWarning() {        super.dIDReceiveMemoryWarning()        // dispose of any resources that can be recreated.    }    @IBAction func addbutton(sender : UIbutton) {        var op1 = operand1.text        var op2 = operand2.text        // Perform the add with the contents of the operand fIElds.        // Print the answer,or "No Result" if add returns nil.        if let answer = brain.add(op1,op2: op2)?.description {            result.text = answer        } else {            result.text = "No Result"        }    }}

MathWhiz.swift

import UIKit// Declare that we implement NSDecimalNumberBehaviors so that we can handle// exceptions without them being raised.class MathWhiz: NSDecimalNumberBehaviors {    var badException = false    // required function of NSDecimalNumberBehaviors protocol    func roundingMode() -> NSRoundingMode {        return .Roundplain    }    // required function of NSDecimalNumberBehaviors protocol    func scale() -> CShort {        return CShort(NSDecimalNoScale)    }    // required function of NSDecimalNumberBehaviors protocol    // Here we process the exceptions    func exceptionDuringOperation(operation: Selector,error: NSCalculationError,leftOperand: NSDecimalNumber,rightoperand: NSDecimalNumber) -> NSDecimalNumber? {        var errorstr = ""        switch(error) {        case .NoError:            errorstr = "NoError"        case .LossOfPrecision:            errorstr = "LossOfPrecision"        case .Underflow:            errorstr = "Underflow"            badException = true        case .Overflow:            errorstr = "Overflow"            badException = true        case .divIDeByZero:            errorstr = "divIDeByZero"            badException = true        }        println("Exception called for operation \(operation) -> \(errorstr)")        return nil    }    // Add two numbers represented by the strings op1 and op2.  Return nil    // if a bad exception occurs.    func add(op1: String,op2: String) -> NSDecimalNumber? {        let dn1 = NSDecimalNumber(string: op1)        let dn2 = NSDecimalNumber(string: op2)        // Init badException to false.  It will be set to true if an        // overflow,underflow,or divIDe by zero exception occur.        badException = false        // Add the NSDecimalNumbers,passing ourselves as the implementor        // of the NSDecimalNumbersBehaviors protocol.        let dn3 = dn1.decimalNumberByAdding(dn2,withBehavior: self)        // Return nil if a bad exception happened,otherwise return the result        // of the add.        return badException ? nil : dn3    }}
总结

以上是内存溢出为你收集整理的异常处理 – 异常处理的Swift异常全部内容,希望文章能够帮你解决异常处理 – 异常处理的Swift异常所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1008451.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存