let vs if != null

Ta Theerasan Tonthongkam
ta tonthongkam
Published in
2 min readJul 14, 2018

let, apply, also ฯลฯ เป็น Scoping Functions ที่มีประโยชน์มากๆ ใน Kotlin มี Blog เขียนอธิบายมากมาย สามารถอ่านที่ Blog อื่นๆ ได้นะครับ

— จบ —

ยังไม่จบ!!!

วันนี้จะมาพูดเรื่องที่เฉพาะเจาะจงของ let ก่อนอื่นเราไปดูความสามารถของ let ก่อน

let

อยู่ใน Kotlin package kotlin-stdlib ที่ทำให้ตัวมันสามารถเรียกฟังก์ชันใน Block แล้ว return ค่าของตัวเองออกไปได้ ซึ่งมี Syntax ดังนี้

inline fun <T, R> T.let(block: (T) -> R): R = block(this)

การใช้ let สามารถใช้ได้ดังนี้

fun getRestaurant(): Restaurantval restaurant = getRestaurant()
println(restaurant.name)
println(restaurant.address)
restaurant.let {
println(it.name)
println(it.address)
}

จากโค้ดข้างต้น การใช้ let ไม่เพียงแค่ทำให้โค้ดสั้นลง แต่เป็นการเขียนโค้ดที่เป็น scope มากขึ้นด้วย

ต่อมาตัวที่จะทำให้ let มีพัลงมากขึ้นคือ ? แน่นอนว่า 2 ตัวนี้ใช้ร่วมกันได้อย่างดี และช่วยให้ชีวิตดีขึ้นเยอะด้วย

?

? หรือ null-check ใน Kotlin ทำให้เราเขียนโค้ดได้ง่ายขึ้น ไม่ต้องคอยมา if != null แน่นอนว่า ในกรณีนี้ สามารถใช้คู่กับ let ได้

fun getRestaurant(): Restaurant?val restaurant = getRestaurant()
println(restaurant?.name ?: "")
println(restaurant?.address ?: "")
restaurant?.let {
println(it.name)
println(it.address)
}

จะสังเกตว่า ใน block ของ let จะการันตีว่า it หรือค่าที่ return จาก restaurant จะไม่เป็น null แน่ๆ แต่แน่นอนว่า โค้ดที่ไม่ใช่ let ก็ยัง เช็ค null ได้ แต่ถ้าเราใช่ elvis มันจะทำให้เราไปค่า “ว่าง” เมื่อ restaurant เป็น null แล้วเราจะทำไงดี ให้ไม่เป็นค่าว่างหล่ะ — if ครับพี่น้อง

If not null VS let

fun getRestaurant(): Restaurant?val restaurant = getRestaurant()
if (restaurant != null) {
println(restaurant.name)
println(restaurant.address)
}
restaurant?.let {
println(it.name)
println(it.address)
}

จะเห็นได้ว่า โค้ดทำงานได้เหมือนกัน แม้ว่าข้อดีของ let จะทำให้โค้ดเป็น scope มาขึ้น แต่ if ของโค้ดข้างบน จะทำหน้าที่แบ่ง scope ให้อยู่

ไม่สิ let ดีกว่า เพราะเขียนแค่ it ก็ได้ — คำตอบนี้จะเป็นข้อดีครับ ถ้าเราใช้ NotePad++ เขียนโค้ด แน่นอนว่า Android Studio แนะนำตัวแปลให้เราได้อยู่แล้ว ข้อดีข้อนี้อาจไม่มีน้ำหนักมากพอในการบอกให้เขียน let ดีกว่า

เรื่องหน้าตา อันสวยกว่า อันไหนไม่สวย แล้วแต่จะตัดสินเลยครับ แต่ไหนๆ ก็ใช้ Kotlin แล้ว ผมแนะนำ ให้ใช่ let เลยดีกว่า อย่างหน้อยก็เอา feature ของภาษามาใช้

แต่มีข้อนึงที่ชัดเจนเลยว่า let ดีกว่า เป็นการการันตีตัวแปรไม่เท่ากับ null จริงๆ ลองดูโค้ดข้างล่างครับ

fun getRestaurant(): Restaurant?var restaurant = getRestaurant()
if (restaurant != null) {
println(restaurant.name)
println(restaurant.address)
}
restaurant?.let {
println(it.name)
println(it.address)
}

เห็นอะไรแตกต่างมั้ยครับ งั้นดูใหม่

fun getRestaurant(): Restaurant?var restaurant = getRestaurant() //ตรงนี้เปลี่ยน
if (restaurant != null) {
restaurant = null //เหตุการณ์นี้อาจเกิดขึ้นได้
println(restaurant.name)
println(restaurant.address)
}
restaurant = null
restaurant?.let {
println(it.name)
println(it.address)
}

ชัดมั้ยครับ — ข้อสังเกตคือ var restaurant ตัวแปรนี้สามารถแปลงค่าได้ตลอดเวลา ไม่เหมือนกับการประกาศด้วย val restaurant แน่นอนว่ากรณีนี้ โค้ดข้างบน nullPointerException แน่นวล ?.let จะโอเคมากๆ เลยสำหรับ ตัวแปรที่เปลี่ยนค่าได้ เพราะ it ใน block ของ let จะไม่สามารถเปลี่ยนค่าได้อีก it จะไม่เท่ากับ null จริงๆ

เหตุการณ์ที่ตัวแปรจะเปลี่ยนค่ามีบ่อยมั้ย?

มีแน่นอน เช่น การ share ตัวแปรใน thread ต่างๆ หรือแม้กระทั้งการ share viewModel ใน fragment ต่างๆ เมื่อค่ามันถูกอัพเดทได้จากหลายๆ ที่ เราไม่สามารถการันตีโดย if ได้เลยว่า หลังจากที่โค้ดรันผ่าน if ไปแล้ว ค่าจะไม่เปลี่ยนอีก เพราะฉนั้นในกรณีนี้ใช้ let ปลอดภัยกว่าเห็น

แต่ถ้าอยากให้โค้ดมี Style พยายามเขียนไปในทำนองเดียวกัน เพื่อรักษาความ Consistantcy ของโค้ดดีกว่านาจา

สรุป

Kotlin มี feature มากมายที่มาทดแทนการเขียนโค้ดแบบเดิมๆ ของ JAVA แน่นอนว่าเหตุผลในการเลือกใช้ ต้องไม่ขึ้นอยู่กับความชอบ แต่ควรขึ้นกับเหตุผลในการเลือกใช้ — Kotlin ยังมี Feature อีกมากมายที่มีข้อดีแอบแฝงอยู่ อย่าลืมเลือกใช้ให้ถูกสถานการณ์ด้วยนะ

ขอบคุณที่อ่านจนจบจ้าาา

— จบ —

--

--