ว้าว คุณเชื่อไหมว่าเรามาถึงภาคที่สี่ของซีรีส์นี้แล้ว? หากคุณยังใหม่กับซีรีส์นี้ ฉันขอแนะนำอย่างยิ่งให้ "กลับไปที่บทนำ" เนื่องจากแต่ละส่วนต่อยอดจากส่วนก่อนหน้า ในส่วนที่สาม เราจะเรียนรู้เกี่ยวกับโฟลว์การควบคุมต่อไปโดยการเรียนรู้เกี่ยวกับลูปประเภทแรกของเรา อย่างไรก็ตาม ก่อนที่เราจะเริ่ม ตรวจสอบให้แน่ใจว่าคุณได้สร้างแพ็คเกจใหม่ชื่อ part_003 และสร้างไฟล์ Kotlin ใหม่ชื่อ app เยี่ยมมาก มาเริ่มกันเลย

ลูปคืออะไร

ลูปเป็นโฟลว์การควบคุมอีกประเภทหนึ่งที่สั่งให้โปรแกรมของคุณทำบางสิ่งซ้ำแล้วซ้ำอีกจนกว่าเงื่อนไขบางอย่างจะเป็นจริง ประเภทที่พบบ่อยที่สุดที่คุณอาจใช้ในโลกแห่งความเป็นจริงคือลูป for ตามด้วยลูป While ในโปรแกรมที่เราจะเขียนวันนี้ เราจะใช้ลูป do while ซึ่งจากประสบการณ์ของผมมีกรณีการใช้งานที่จำกัดมาก แต่จะสมบูรณ์แบบสำหรับสิ่งที่เราต้องทำ นอกจากนี้ ไม่ต้องกังวลในส่วน 004 และ 005 ฉันตั้งใจจะลงรายละเอียดเพิ่มเติมเกี่ยวกับลูปทั่วไป

มาทำให้ตัวตรวจสอบแปลก ๆ ของเราดีขึ้นกันเถอะ

จนถึงจุดนี้โปรแกรมของเรามีความก้าวหน้าเป็นเส้นตรงมาก เราขอให้คุณป้อนข้อมูลจากแป้นพิมพ์ เราจัดการอินพุตนั้น และจากนั้นจึงให้เอาต์พุตแก่คุณ หากเราต้องการให้อินพุตอื่นแก่โปรแกรม เราต้องรีสตาร์ทโปรแกรม ซึ่งไม่เหมาะนัก ดังนั้นสำหรับโปรแกรมนี้ เราจะเพิ่มลูปเพื่อให้คุณสามารถป้อนอินพุตได้มากขึ้นโดยไม่ต้องรีสตาร์ท

do {
    // this is where you execute your code
} while (/* some condition is true */)

นี่คือไวยากรณ์พื้นฐานของลูป do while เราสั่งให้โปรแกรมของเราทำอะไรสักอย่าง และหลังจากนั้นมันจะตรวจสอบว่าเงื่อนไขบางอย่างเป็นจริงหรือไม่ หากเงื่อนไขเป็นจริง เราจะกลับไปที่จุดเริ่มต้นของลูปและรันโค้ดนั้นอีกครั้ง นี่เป็นลูปเดียวที่ช่วยให้คุณสามารถรันโค้ดได้อย่างน้อยหนึ่งครั้งโดยไม่คำนึงถึงเงื่อนไข (เนื่องจากเราตรวจสอบเงื่อนไขหลังจากที่เราได้รันโค้ดแล้ว) สำหรับโปรแกรมของเรา เราต้องการตรวจสอบว่าอย่างน้อยหนึ่งตัวเลขเป็นเลขคู่หรือคี่ แต่เราอาจต้องการทำซ้ำหลายๆ ครั้ง ดังนั้นการวนซ้ำนี้จึงสมบูรณ์แบบสำหรับเพียงตัวเลขนั้น

เรามาเริ่มส่วน 002 และล้อมโค้ดของเราด้วยไวยากรณ์ด้านบนกันดีกว่า หลังจากที่เราแสดงว่าตัวเลขเป็นเลขคู่หรือคี่ เราจะแจ้งให้ผู้ใช้ทราบหากพวกเขาต้องการตรวจสอบหมายเลขอื่น หากพวกเขาป้อน y เราก็จะตรวจสอบ ไม่เช่นนั้นเราจะออกจากลูปและขอบคุณผู้ใช้ที่ใช้โปรแกรมของเรา ลองทำสิ่งนี้ด้วยตัวคุณเอง โค้ดด้านล่างจะเป็นวิธีแก้ปัญหานี้

fun main(args : Array<String>) {

    val userInput = Scanner(System.`in`)
    do {
        // Prompt the user to enter a number.
        System.out.print("Enter a number to evaluate: ")
        val number = userInput.nextLine().toInt()

        // If it is divisible by 2, then it's even
        if (number % 2 == 0) {
            System.out.println("$number is even!")
        } else {
            // Otherwise it is odd
            System.out.println("$number is odd!")
        }

        System.out.print("Do you want to continue? (y/n): ")
    } while (userInput.nextLine() == "y")

    System.out.println("Thanks for using the even/odd number checker!")
}

มีบางส่วนเกี่ยวกับเรื่องนี้ที่เป็นของใหม่ ขั้นแรก เราได้ล้อมรอบโปรแกรมดั้งเดิมส่วนใหญ่ของเราไว้ในบล็อก do {...} ฉันทิ้งการประกาศตัวแปรไว้สำหรับ userInput ไว้นอกลูป เนื่องจากมันไม่สมเหตุสมผลเลยที่จะประกาศสิ่งนั้นซ้ำทุกครั้งที่วนซ้ำในลูป ฉันยังเพิ่มการโทรอีกครั้งเพื่อพิมพ์บรรทัดถามผู้ใช้ว่าต้องการดำเนินการต่อหรือไม่ จากนั้นในส่วน while (...) ฉันจะตรวจสอบว่า userInput เท่ากับอักขระ y หรือไม่ หากไม่เป็นเช่นนั้น เราจะพิมพ์บรรทัดใหม่เพื่อขอบคุณผู้ใช้ที่ใช้โปรแกรมของเรา จากนั้นโปรแกรมก็จะเสร็จสมบูรณ์

มาทำสิ่งนี้ด้วยวิธี Kotlin

จนถึงตอนนี้ฉันได้เขียนบทความเหล่านี้ในลักษณะที่ค่อนข้างพื้นฐานและเข้าใจง่าย ฉันอยากจะขอบคุณผู้เขียน Medium Ľuboš Mudrák ที่ชี้ให้เห็นว่า Kotlin นำเสนอวิธีที่ง่ายกว่าในการอ่านและพิมพ์บรรทัดจากคอนโซล (คอนโซลคือสิ่งที่เราใช้งานโปรแกรมของเรา) ดังนั้นเราจะอัปเดตโปรแกรมของเราเพื่อใช้วิธีใหม่นั้นและแนะนำแนวคิดของ nullability ด้วย

ดังนั้นไปข้างหน้าและลบตัวแปร userInput ออกจากโปรแกรมของคุณ ในตำแหน่งที่คุณโทรหา userInput ให้แทนที่ด้วย readline() คุณจะสังเกตเห็นว่า IntelliJ กำลังส่งสัญญาณว่ามีบางอย่างไม่ถูกต้อง อย่าลังเลที่จะดูว่าคุณสามารถแก้ไขได้หรือไม่ (แต่อย่ารู้สึกแย่ถ้าคุณติดขัด) ถัดไปแทนที่การโทรทั้งหมดของคุณไปที่ System.out.println(...) ด้วยเพียง println(...)และสามารถทำได้เหมือนกันสำหรับ System.out.print(...) ยกเว้นว่าจะเป็น print(...)

ตอนนี้เรากลับมาที่ข้อความแสดงข้อผิดพลาดที่คุณอาจยังคงเห็นอยู่ เมื่อคุณโทร readline() มีโอกาสที่มันจะคืนค่า null เป็นค่า โดยพื้นฐานแล้วในการเขียนโปรแกรม null หมายความว่าไม่มีอะไรอยู่ที่นั่น ดังนั้นหากคุณพยายามดำเนินการกับค่า null โปรแกรมของคุณจะเสียหาย แนวคิดของ null ได้รับการอ้างถึงว่าเป็นข้อผิดพลาดพันล้านดอลลาร์ (เนื่องจากข้อยกเว้นของตัวชี้ null ทำให้บริษัทต้องเสียเงินเป็นจำนวนมาก) คุณสามารถ อ่านเพิ่มเติมเกี่ยวกับสาเหตุที่ null จึงเป็นความคิดที่ไม่ดีได้ที่นี่

อย่างไรก็ตาม นี่คือสิ่งที่เราต้องจัดการ ในภาษาเก่าๆ เช่น Java มันเป็นกระบวนการที่ยุ่งยากมาก Kotlin ทำหลายอย่างเพื่อ "ปกป้องเราจากค่าว่าง" วิธีหนึ่งที่ Kotlin ทำได้ก็คือ จะไม่ยอมให้คุณคอมไพล์โปรแกรมที่สามารถดำเนินการกับค่า Null ได้โดยไม่ได้ตั้งใจ นั่นคือเหตุผลที่คุณได้รับข้อความแสดงข้อผิดพลาด นี่คือลักษณะของโปรแกรมของฉันหลังจากที่ฉันป้องกันค่าว่าง

fun main(args : Array<String>) {

    do {
        // Prompt the user to enter a number.
        print("Enter a number to evaluate: ")
        val number = readLine()?.let { it.toInt() }

        number?.let {
            // If it is divisible by 2, then it's even
            if (it % 2 == 0) {
                println("$number is even!")
            } else {
                // Otherwise it is odd
                println("$it is odd!")
            }
        }

        print("Do you want to continue? (y/n): ")
    } while (readLine() == "y")

    println("Thanks for using the even/odd number checker!")

}

คุณจะสังเกตเห็นว่าฉันใช้เครื่องหมายคำถามก่อนโทร let ทั้งสองสิ่งนี้เป็นสิ่งที่ช่วยป้องกันค่าว่าง เครื่องหมายคำถามบอกให้โปรแกรมทำบางอย่างหากตัวแปรไม่เป็นโมฆะเท่านั้น หากเป็นโมฆะ เราจะไม่ดำเนินการ จากนั้น number จะเป็น null คีย์เวิร์ด let ช่วยให้คุณสามารถส่งผ่านค่าของออบเจ็กต์ (ตัวแปร) และดำเนินการบางอย่างกับมันได้ นอกจากนี้เรายังใช้คีย์เวิร์ด it เพื่ออ้างถึงออบเจ็กต์ที่ถูกส่งเข้ามา (ในกรณีนี้คือค่าที่อ่านจากแป้นพิมพ์)

ดังนั้นในภาษาอังกฤษธรรมดา val number = readLine()?.let { it.toInt() } สามารถอ่านได้ประมาณนี้: ถ้า readline ไม่เป็นโมฆะ ให้ เราแปลง มัน เป็นจำนวนเต็มและตั้งค่า number เป็น ค่านั้น

โปรดทราบว่ายังมีโอกาสที่ number จะเป็นโมฆะได้ ถ้า readLine() เป็นโมฆะ นั่นคือเหตุผลที่เรายังโทรไปที่ let ที่ number ในบรรทัดถัดไป โปรดสังเกตว่าภายในบล็อกนั้น it และ number สามารถใช้เพื่ออ้างถึงสิ่งเดียวกันได้ สำหรับตอนนี้ หากคุณเข้าใจได้ง่ายขึ้น ก็สามารถเพิกเฉยต่อ it และใช้ตัวแปร number ได้เลย แค่รู้ว่าวิธี Kotlin ในการทำสิ่งที่คุณน่าจะใช้คีย์เวิร์ด it แทน

ด้วยเหตุนี้ ผมขอปรับโครงสร้างใหม่อีกครั้งเพื่อแสดงให้คุณเห็นว่าโปรแกรมของคุณจะดูเป็นอย่างไรเมื่อใช้คีย์เวิร์ด let และ it ฉันจะย้ายการประกาศ number ให้อยู่ในบล็อก let แรก ซึ่งจะทำให้เราสามารถลบ let ที่สองได้อย่างสมบูรณ์

fun main(args : Array<String>) {

    do {
        // Prompt the user to enter a number.
        print("Enter a number to evaluate: ")
        readLine()?.let {
            val number = it.toInt()

            // If it is divisible by 2, then it's even
            if (number % 2 == 0) {
                println("$number is even!")
            } else {
                // Otherwise it is odd
                println("$number is odd!")
            }
        }

        print("Do you want to continue? (y/n): ")
    } while (readLine() == "y")

    println("Thanks for using the even/odd number checker!")

}

ตอนนี้เราจะเรียกใช้โค้ดก็ต่อเมื่อ readLine() ไม่เป็นโมฆะ เมื่อเรารู้ว่าไม่เป็นโมฆะ เราจะประกาศตัวแปร number ซึ่งเรารู้ว่าจะไม่เป็นโมฆะ และสามารถรันโปรแกรมได้อย่างปลอดภัยเหมือนที่เราเคยทำมาก่อน จริงๆ แล้วฉันคิดว่าวิธีนี้น่าจะเป็นทางออกที่หรูหราที่สุด

แล้วคุณรู้สึกอย่างไรกับการเรียนรู้วิธีเขียนโค้ดภาคนี้? ข้อมูลมากเกินไปไม่เพียงพอหรือถูกต้อง? มีพื้นที่ใดบ้างที่คุณต้องการให้ฉันขยายเพิ่มเติมในบทความต่อๆ ไป เมื่อคุณพร้อมที่จะดำเนินการต่อ ตอนที่ 004 พร้อมใช้งานแล้ว