Pengecualian Coba & Tangkap Kotlin

Saya seorang programmer Kotlin yang sangat pemula. Apa yang saya lakukan salah dengan kode coba & tangkap? Apakah ada masalah pada bagian try atau 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))
}

person Ozzini    schedule 16.12.2020    source sumber
comment
quantity == 0 bukanlah pernyataan yang valid   -  person AvroVulcan    schedule 16.12.2020
comment
Anda memerlukan if (quantity == 0) println("Can't be 0!"). Selain itu, tangkapan kedua tidak berguna karena toInt sebenarnya berada di luar blok try.   -  person user    schedule 16.12.2020


Jawaban (1)


Ada beberapa konsep yang Anda salah.

Mari kita mulai dengan membicarakan hal ini:

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

Beberapa masalah. Pertama, assignment yang sebenarnya adalah check.

quantity == 0 tidak akan mengubah nilai quantity ia hanya akan memeriksa apakah nilainya sama dengan 0. Hasil pemeriksaan ini (a Boolean) diabaikan sepenuhnya.

Jika Anda ingin memeriksa apakah quantity adalah 0, Anda perlu melakukannya dalam pernyataan if.

Kebingungan kedua yang menurut saya Anda miliki adalah mengenai apa yang dilakukan blok try/catch. Ia mencoba beberapa bagian kode, dan jika kode tersebut gagal (alias kode memunculkan pengecualian), tangkapan dapat digunakan untuk mengurangi risiko penghentian prosedur. Dalam beberapa kasus, tidak apa-apa jika prosedur dihentikan, lalu tangkapan digunakan untuk menulis info lebih lanjut di konsol, untuk mengesampingkan pesan pengecualian, atau untuk memanggil potongan kode lain sebelum proses berakhir.

Kebingungan ketiga ada di blok catch. catch (e: Exception) akan menangkap semua kemungkinan pengecualian (tetapi tidak semua kemungkinan Throwables). Artinya, blok catch kedua dari e: ArithmeticException tidak akan pernah terjadi karena blok pertama lebih umum.

Mempertimbangkan hal itu, dan dengan asumsi Anda ingin proses benar-benar berhenti ketika inputnya 0, yang perlu Anda lakukan adalah:

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

OR

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

Tapi, sumOfDigits Anda sudah memeriksa apakah angkanya kurang dari 0, mengapa tidak memeriksanya jika kurang dari 1? Karena kita tidak menginginkan angka 0, memulai dari 1 adalah proses alami yang harus kita ikuti.

Dengan mempertimbangkan hal ini, maka kita mendapatkan ini:

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
}

Hal ini juga dapat ditingkatkan.

  • quantity tidak perlu menjadi variabel, kami tidak pernah mengubah nilainya.
  • Properti digit dalam fungsi sumOfDigits berlebihan, karena kita dapat langsung menetapkan hasil number % 10 ke skor.
  • Jika kita benar-benar menginginkannya, kita dapat mencoba menangkap pengecualian yang akan terjadi jika pengguna memasukkan karakter bukan angka.
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
}

Sekarang, sebagai pengembang Kotlin, saya akan menulis ini dengan cara yang berbeda, dan saya tidak akan menyarankan pemula untuk menggunakan Kotlin seperti ini. Namun saya yakin masih menarik bagi Anda untuk mengetahui bahwa prosedur Anda dapat diminimalkan dengan cukup mudah. (Catatan, ini tidak dapat dibaca, dan memerlukan dokumentasi yang tepat jika Anda memutuskan untuk membuat kode dengan cara ini)

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)
}
person Alex.T    schedule 16.12.2020