【问题标题】:Kotlin Try&Catch ExceptionKotlin Try&Catch 异常
【发布时间】:2020-12-16 19:48:17
【问题描述】:

我是一个非常初学者的 Kotlin 程序员。我在尝试捕获代码时做错了什么? try 部分或 catch 部分有问题吗?

fun sumOfDigits(quantity: Int): Int {
    var score = 0
    var digit: Int
    var number: Int = quantity

    if (number < 0) throw ArithmeticException("Give number >0!")

    while (number > 0)
    {
        digit = number%10
        score += digit
        number /=10
    }
    return score
}
fun main()
{
    println("Give number: ")
    var quantity: Int = readLine()!!.toInt()

    try {
        quantity == 0
    }
    catch (e: Exception){
        println("Can't be 0!")
    }
    catch (e: ArithmeticException){
        println(e.message)
    }
    println(sumOfDigits(quantity))
}

【问题讨论】:

  • quantity == 0 本身不是一个有效的声明
  • 您需要if (quantity == 0) println("Can't be 0!")。此外,第二个捕获是无用的,因为实际的 toInttry 块之外。

标签: kotlin exception try-catch


【解决方案1】:

有几个概念你弄错了。

让我们从这个开始:

 try {
        quantity == 0
    }
    catch (e: Exception){
        println("Can't be 0!")
    }
    catch (e: ArithmeticException){
        println(e.message)
    }
    println(sumOfDigits(quantity))

几个问题。首先,assignment 实际上是一个check

quantity == 0 不会改变 quantity 的值,它只会检查它是否等于 0。此检查的结果(Boolean)被完全忽略。

如果您想检查quantity 是否为0,您需要在if 语句中进行。

我认为您的第二个困惑是关于 try/catch 块的作用。它尝试一些代码,如果该代码失败(也就是代码抛出异常),catch 可用于降低过程停止的风险。在某些情况下,过程停止是可以的,然后catch用于在控制台中写入更多信息,覆盖异常的消息,或者在过程结束之前调用其他代码。

第三个混淆是在catch 块上。 catch (e: Exception) 将捕获所有可能的异常(但不是所有可能的 Throwables)。这意味着e: ArithmeticException 的第二个catch 块将永远不会发生,因为第一个块更通用。

考虑到这一点,并假设您希望进程在输入为 0 时真正停止,那么您需要做的就是:

if(condition==0) return //close the program silently

if(condition==0) error("Can't be 0") //throw an exception with this message

但是,您的sumOfDigits 已经检查了数字是否小于 0,为什么不让它检查它是否小于 1?由于我们不想要 0,所以从 1 开始是我们应该遵循的自然过程。

考虑到这一点,我们得到这个:

fun main() {
    println("Give number: ")
    var quantity: Int = readLine()!!.toInt()

    println(sumOfDigits(quantity))
}


fun sumOfDigits(quantity: Int): Int {
    var score = 0
    var digit: Int
    var number: Int = quantity

    if (number < 1) throw ArithmeticException("Give number >0!")

    while (number > 0) {
        digit = number % 10
        score += digit
        number /= 10
    }
    return score
}

这也可以改进。

  • quantity 不需要可变,我们从不改变它的值。
  • sumOfDigits 函数中的digit 属性是多余的,因为我们可以直接将number % 10 的结果赋值给分数。
  • 如果我们真的需要,我们可以尝试捕获用户输入非数字字符时会发生的异常。
fun main() {
    println("Give number: ")
    val userInput: String = readLine() ?: error("Please provide an input") //this exception is thrown when the input is null (due to the Elvis operator `?:`)
    val number: Int

    try{
        number = userInput.toInt()
    }catch (e: NumberFormatException){
        println("A number needs to be provided. Input `$userInput` cannot be read as number")
        return 
        /*this will just close our procedure, we could also just throw our own exception
          instead of hte println, or just leave the normal exception propagate*/
    }

    println(sumOfDigits(number))
}


fun sumOfDigits(quantity: Int): Int {
    var score = 0
    var number: Int = quantity

    if (number < 1) throw ArithmeticException("Give number >0!")

    while (number > 0) {
        score += number % 10
        number /= 10
    }
    return score
}

现在,作为一名 Kotlin 开发人员,我会以完全不同的方式编写此代码,并且我不建议初学者像这样使用 Kotlin。但我相信你仍然很高兴知道你的程序可以很容易地最小化。 (注意,这是不可读的,如果您决定以这种方式编写代码,则需要适当的文档)

fun main() {
    println("Give number: ")
    //will take an input from the user and throw an exception if the input is null
    val input = readLine() ?: error("No input given")

    //will throw NumberFormatException if the input is not a number. We are ignoring the actual result of the call itself
    input.toInt() 
    
    /*
        will take each char of the string and create a sum with the given selector. Since the given selector is
        the char itself minus 0, it will actually sum each char, in our case, each digit
    */
    val sum = input.sumBy { it - '0'}
    
    println(sum)
}

【讨论】:

    猜你喜欢
    • 2011-09-16
    • 2011-04-01
    • 1970-01-01
    • 2013-03-09
    • 2015-06-21
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多