การแปลงโดยนัย
ใช้อย่างระมัดระวัง
การแปลงโดยนัย เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
การแปลงโดยนัยคืออะไร
การแปลงโดยนัยจะเปลี่ยนค่าจากชนิดหนึ่งเป็นอีกชนิดหนึ่งโดยอัตโนมัติเมื่อคอมไพเลอร์ต้องการ การแปลงนี้ช่วยให้ส่วนเชื่อมต่อการเขียนโปรแกรมใช้งานสะดวกขึ้น แต่ต้องใช้อย่างระมัดระวัง เพราะซ่อนสิ่งที่กำลังเกิดขึ้น
object Main {
import scala.language.implicitConversions
implicit def intToString(x: Int): String = s"number-$x"
def main(args: Array[String]): Unit = {
val s: String = 42
println(s)
}
}คอมไพเลอร์ใช้การแปลงเหล่านี้อย่างไร
เมื่อชนิดของค่าไม่ตรงกับชนิดที่คาดหวัง คอมไพเลอร์จะค้นหาการแปลงโดยนัยที่แก้ความไม่ตรงกันนั้น แล้วแทรกการแปลงให้โดยไม่แสดงให้เห็น
object Main {
import scala.language.implicitConversions
implicit def doubleToInt(d: Double): Int = d.toInt
def addTen(x: Int): Int = x + 10
def main(args: Array[String]): Unit = {
println(addTen(3.9))
}
}การเปิดใช้ความสามารถนี้
การกำหนดการแปลงโดยนัยจำเป็นต้องนำเข้า scala.language.implicitConversions มิฉะนั้นคอมไพเลอร์จะแจ้งคำเตือน นี่เป็นการเพิ่มข้อจำกัดโดยตั้งใจเพื่อไม่สนับสนุนการใช้มากเกินไป
object Main {
import scala.language.implicitConversions
case class Celsius(value: Double)
implicit def doubleToCelsius(d: Double): Celsius = Celsius(d)
def describe(c: Celsius): String = s"${c.value} C"
def main(args: Array[String]): Unit = {
println(describe(36.6))
}
}การห่อหุ้มเพื่อเพิ่มเมธอด (รูปแบบเดิม)
ก่อนมีเมธอดส่วนขยาย การแปลงโดยนัยเป็นวิธีเพิ่มเมธอดให้ชนิดที่มีอยู่แล้วผ่านคลาสห่อหุ้ม ซึ่งเรียกกันว่ารูปแบบปรับปรุงไลบรารีด้วยตนเอง
object Main {
import scala.language.implicitConversions
class RichInt2(x: Int) {
def squared: Int = x * x
}
implicit def toRich(x: Int): RichInt2 = new RichInt2(x)
def main(args: Array[String]): Unit = {
println(5.squared)
}
}อันตราย: ความประหลาดใจที่เงียบงัน
เนื่องจากการแปลงมองไม่เห็น ณ จุดเรียกใช้ จึงอาจทำให้เกิดพฤติกรรมที่สับสนและข้อผิดพลาดที่ติดตามสาเหตุได้ยาก การพิมพ์ผิดอาจยังคอมไพล์ผ่านโดยบังเอิญกระตุ้นให้เกิดการแปลง
object Main {
import scala.language.implicitConversions
implicit def boolToInt(b: Boolean): Int = if (b) 1 else 0
def main(args: Array[String]): Unit = {
val total = true + 4 // surprising! becomes 1 + 4
println(total)
}
}เลือกใช้การแปลงอย่างชัดเจน
บ่อยครั้งทางเลือกที่ปลอดภัยที่สุดคือใช้เมธอดที่มีชื่อชัดเจนแทนการแปลงโดยนัย โค้ดอาจยาวขึ้น แต่ผู้อ่านเข้าใจได้ทันที
object Main {
case class Celsius(value: Double)
def fromDouble(d: Double): Celsius = Celsius(d)
def main(args: Array[String]): Unit = {
val c = fromDouble(20.5)
println(c)
}
}Scala 3: คลาสชนิด Conversion
Scala 3 ทำให้การแปลงชัดเจนขึ้นผ่านอินสแตนซ์ given Conversion[A, B] วิธีนี้สื่อเจตนาได้ชัดกว่า และยังจำเป็นต้องนำเข้าความสามารถของภาษา
import scala.language.implicitConversions
object Main:
given Conversion[Int, String] = (x: Int) => s"val-$x"
def main(args: Array[String]): Unit =
val s: String = 7
println(s)การแปลงมีผลได้เพียงครั้งเดียว
คอมไพเลอร์จะใช้การแปลงโดยนัยไม่เกินหนึ่งครั้งในแต่ละครั้ง โดยจะไม่ต่อการแปลงสองครั้งเพื่อเชื่อมชนิดที่ไม่ตรงกัน ซึ่งช่วยจำกัดความประหลาดใจ
object Main {
import scala.language.implicitConversions
implicit def intToStr(x: Int): String = x.toString
def needString(s: String): Int = s.length
def main(args: Array[String]): Unit = {
println(needString(12345))
}
}ค้นพบการแปลงได้ที่ใด
เช่นเดียวกับค่าโดยนัยอื่น ๆ การแปลงจะถูกแก้ค่าจากขอบเขตเฉพาะที่ การนำเข้า และออบเจ็กต์คู่หู การเก็บการแปลงไว้ในการนำเข้าที่ตั้งชื่ออย่างชัดเจนช่วยให้มองเห็นว่ามีการใช้งานอยู่
object Conversions:
import scala.language.implicitConversions
implicit def strToLen(s: String): Int = s.length
object Main:
import Conversions._
def main(args: Array[String]): Unit =
val n: Int = "hello"
println(n)กรณีที่การแปลงเหมาะสม
การใช้งานที่เหมาะสม ได้แก่ การทำงานร่วมกับชนิดของ Java ตัวช่วยขยายชนิดตัวเลข และขอบเขตระหว่างไลบรารี นอกเหนือจากนั้น ควรเลือกใช้เมธอดส่วนขยายหรือฟังก์ชันที่ระบุอย่างชัดเจน
object Main {
import scala.language.implicitConversions
case class Meters(v: Double)
implicit def metersToDouble(m: Meters): Double = m.v
def main(args: Array[String]): Unit = {
val d: Double = Meters(3.5)
println(d * 2)
}
}หลักโดยสังเขป
หากผู้อ่านดูจากโค้ดแล้วไม่สามารถบอกได้ว่ามีการแปลงเกิดขึ้น นั่นเป็นสัญญาณเตือน ควรเลือกใช้การแปลงโดยนัยเป็นทางเลือกสุดท้ายหลังจากพิจารณาเมธอดส่วนขยายและการเรียกใช้อย่างชัดเจนแล้ว
object Main {
// Explicit and obvious - usually better
case class Price(cents: Int)
def toDollars(p: Price): Double = p.cents / 100.0
def main(args: Array[String]): Unit = {
println(toDollars(Price(1599)))
}
}ตรวจสอบอย่างรวดเร็ว
ความเสี่ยงหลักของการแปลงโดยนัยคืออะไร
สรุปทบทวน
คุณได้เรียนรู้การแปลงโดยนัยและข้อควรระวังแล้ว:
- ระบบจะแปลงชนิดหนึ่งเป็นอีกชนิดหนึ่งโดยอัตโนมัติเมื่อชนิดไม่ตรงกัน
- ต้องใช้
import scala.language.implicitConversions - Scala 3 ใช้
given Conversion[A, B] - ระบบจะใช้การแปลงได้ครั้งละหนึ่งรายการเท่านั้น
- ควรใช้เท่าที่จำเป็น และเลือกใช้เมธอดส่วนขยายหรือการเรียกอย่างชัดเจนแทน
คำถามที่พบบ่อย
บทเรียน “การแปลงโดยนัย” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การแปลงโดยนัย” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การแปลงโดยนัย”
ใช้อย่างระมัดระวัง คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การแปลงโดยนัย” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม
ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พารามิเตอร์โดยนัย
- given/using ใน Scala 3
- การแปลงโดยนัย
- เมธอดส่วนขยาย