แนวปฏิบัติที่ดี
ทำให้ตัวดำเนินการมีความหมายที่เข้าใจง่าย
แนวปฏิบัติที่ดี เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
รักษาความเป็นธรรมชาติของตัวดำเนินการ
โอเวอร์โหลดตัวดำเนินการเฉพาะเมื่อความหมายของตัวดำเนินการนั้นชัดเจนเท่านั้น การใช้ + กับเวกเตอร์นั้นเข้าใจได้ แต่การให้ + หมายถึงการส่งอีเมลนั้นไม่ชัดเจน
data class Vec(val x: Int, val y: Int) {
operator fun plus(o: Vec) = Vec(x + o.x, y + o.y)
}
fun main() {
println(Vec(1, 2) + Vec(3, 4))
}รักษาความหมายที่คาดหวัง
ยึดหลักพีชคณิตตามปกติ: a + b ควรให้ความรู้สึกว่าสลับที่ได้สำหรับชนิดข้อมูลที่สมมาตร และไม่ควรทำให้ผู้อ่านประหลาดใจ
data class Money(val cents: Int) {
operator fun plus(o: Money) = Money(cents + o.cents)
}
fun main() {
println(Money(100) + Money(50))
}ควรเลือกใช้ความไม่เปลี่ยนรูป
ตัวดำเนินการอย่าง plus ควรส่งคืนค่าใหม่แทนการเปลี่ยนแปลงตัวรับ ซึ่งสอดคล้องกับพฤติกรรมของตัวเลข
data class Point(val x: Int) {
operator fun plus(o: Point) = Point(x + o.x)
}
fun main() {
val a = Point(1)
val b = a + Point(2)
println("${a.x} ${b.x}")
}plus กับ plusAssign
กำหนด plus สำหรับค่าที่ไม่เปลี่ยนรูป และกำหนด plusAssign สำหรับการเปลี่ยนแปลงคอนเทนเนอร์แบบแก้ไขภายในตำแหน่งเดิม หลีกเลี่ยงการกำหนดทั้งสองแบบให้มีพฤติกรรมขัดแย้งกัน
class Cart {
val items = mutableListOf<String>()
operator fun plusAssign(item: String) { items.add(item) }
}
fun main() {
val c = Cart()
c += "book"
println(c.items)
}ให้ชนิดที่ส่งคืนสอดคล้องกัน
ส่งคืนชนิดข้อมูลเดียวกันจากตัวดำเนินการแบบไบนารี เพื่อให้สามารถเชื่อมผลลัพธ์ต่อกันได้อย่างเป็นธรรมชาติ
data class N(val v: Int) {
operator fun plus(o: N) = N(v + o.v)
}
fun main() {
println((N(1) + N(2) + N(3)).v)
}อย่าโอเวอร์โหลดเพียงเพื่อความซับซ้อน
หากฟังก์ชันที่มีชื่ออ่านเข้าใจได้ดีกว่า ก็ควรใช้ฟังก์ชันนั้น ตัวดำเนินการเหมาะสำหรับความหมายที่เกี่ยวกับตัวเลขหรือคอนเทนเนอร์อย่างแท้จริง ไม่ใช่สำหรับปริศนา
data class Log(val lines: List<String>) {
fun append(line: String) = Log(lines + line)
}
fun main() {
println(Log(emptyList()).append("start").lines)
}รักษาความสอดคล้องของ equals และ hashCode
หากคุณโอเวอร์โหลดการเปรียบเทียบหรือความเท่ากัน ต้องรักษา equals และ hashCode ให้สอดคล้องกัน เพื่อป้องกันไม่ให้คอลเลกชันทำงานผิดพลาด
data class Id(val v: Int)
fun main() {
val set = hashSetOf(Id(1), Id(1))
println(set.size)
}ระวังลำดับความสำคัญของตัวดำเนินการ
ตัวดำเนินการที่โอเวอร์โหลดยังคงใช้ลำดับความสำคัญแบบเดียวกับตัวดำเนินการในตัว ออกแบบให้ลำดับความสำคัญตามธรรมชาติสร้างผลลัพธ์ที่คาดหวัง
data class N(val v: Int) {
operator fun plus(o: N) = N(v + o.v)
operator fun times(o: N) = N(v * o.v)
}
fun main() {
println((N(2) + N(3) * N(4)).v)
}จัดทำเอกสารสำหรับตัวดำเนินการที่คาดเดาได้ยาก
หากตัวดำเนินการทำสิ่งที่ไม่ชัดเจน ควรเพิ่มความคิดเห็นหรือเอกสารประกอบ เพื่อไม่ให้ผู้เรียกใช้เข้าใจผิด
data class Range2(val start: Int, val end: Int) {
// contains: is value inside the range?
operator fun contains(v: Int) = v in start..end
}
fun main() {
println(5 in Range2(1, 10))
}ใช้ contains สำหรับ in
ตัวดำเนินการ in จะจับคู่กับ contains โอเวอร์โหลดตัวดำเนินการนี้เฉพาะเมื่อสามารถนิยามการเป็นสมาชิกสำหรับชนิดข้อมูลของคุณได้อย่างชัดเจน
class Team(val members: List<String>) {
operator fun contains(name: String) = name in members
}
fun main() {
val t = Team(listOf("Ann", "Bo"))
println("Ann" in t)
}หากไม่แน่ใจ ให้ใช้ฟังก์ชัน
เมธอดที่มีชื่อสื่อความหมายชัดเจนมักปลอดภัยกว่าตัวดำเนินการที่เข้าใจได้ยาก ใช้การโอเวอร์โหลดเฉพาะเมื่อช่วยให้อ่านโค้ดได้ดีขึ้นอย่างแท้จริง
data class Temperature(val c: Int) {
fun warmerThan(o: Temperature) = c > o.c
}
fun main() {
println(Temperature(30).warmerThan(Temperature(20)))
}ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจเกี่ยวกับแนวปฏิบัติที่ดีในการโอเวอร์โหลดตัวดำเนินการ
สรุปทบทวน
คุณได้เรียนรู้แนวปฏิบัติที่ดีในการโอเวอร์โหลดตัวดำเนินการ:
- โอเวอร์โหลดเฉพาะเมื่อความหมายชัดเจนและเป็นไปตามธรรมเนียม
- ควรเลือกใช้ค่าที่ไม่เปลี่ยนรูปและส่งคืนชนิดเดียวกัน เพื่อให้เชื่อมผลลัพธ์ต่อกันได้
- แยก
plusซึ่งทำงานกับค่า ออกจากplusAssignซึ่งใช้เปลี่ยนแปลงค่า - รักษา
equals/hashCodeให้สอดคล้องกัน และเลือกใช้ฟังก์ชันที่มีชื่อเมื่ออ่านเข้าใจได้ชัดเจนกว่า
data class V(val x: Int) {
operator fun plus(o: V) = V(x + o.x)
}
fun main() {
println((V(2) + V(5)).x)
}คำถามที่พบบ่อย
บทเรียน “แนวปฏิบัติที่ดี” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “แนวปฏิบัติที่ดี” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “แนวปฏิบัติที่ดี”
ทำให้ตัวดำเนินการมีความหมายที่เข้าใจง่าย คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “แนวปฏิบัติที่ดี” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม
ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ