ใน Scala เราสามารถใช้อย่างน้อยสองวิธีในการติดตั้งประเภทที่มีอยู่หรือแบบใหม่ สมมติว่าเราต้องการแสดงว่าบางสิ่งสามารถหาปริมาณได้โดยใช้Int
. เราสามารถกำหนดลักษณะต่อไปนี้
การแปลงโดยนัย
trait Quantifiable{ def quantify: Int }
จากนั้นเราสามารถใช้การแปลงโดยนัยเพื่อหาจำนวนเช่น Strings and Lists
implicit def string2quant(s: String) = new Quantifiable{
def quantify = s.size
}
implicit def list2quantifiable[A](l: List[A]) = new Quantifiable{
val quantify = l.size
}
หลังจากนำเข้าสิ่งเหล่านี้เราสามารถเรียกใช้เมธอดquantify
ในสตริงและรายการ quantify
โปรดทราบว่ารายการเชิงปริมาณเก็บความยาวของมันจึงหลีกเลี่ยงการสำรวจเส้นทางที่มีราคาแพงของรายการได้ที่โทรตามมากับ
พิมพ์คลาส
อีกทางเลือกหนึ่งคือการกำหนด "พยาน" Quantified[A]
ที่ระบุว่าบางประเภทA
สามารถหาปริมาณได้
trait Quantified[A] { def quantify(a: A): Int }
จากนั้นเราจะจัดเตรียมอินสแตนซ์ของคลาสประเภทนี้สำหรับString
และที่List
ใดที่หนึ่ง
implicit val stringQuantifiable = new Quantified[String] {
def quantify(s: String) = s.size
}
และถ้าเราเขียนวิธีการที่ต้องการหาจำนวนอาร์กิวเมนต์เราจะเขียน:
def sumQuantities[A](as: List[A])(implicit ev: Quantified[A]) =
as.map(ev.quantify).sum
หรือใช้ไวยากรณ์ขอบเขตบริบท:
def sumQuantities[A: Quantified](as: List[A]) =
as.map(implicitly[Quantified[A]].quantify).sum
แต่จะใช้วิธีไหนเมื่อไหร่?
ตอนนี้มาถึงคำถาม ฉันจะตัดสินใจระหว่างสองแนวคิดนี้ได้อย่างไร
สิ่งที่ฉันสังเกตเห็นจนถึงตอนนี้
พิมพ์คลาส
- ประเภทคลาสอนุญาตให้ใช้ไวยากรณ์ที่มีขอบเขตบริบทที่ดี
- ด้วยคลาสประเภทฉันไม่ได้สร้างออบเจ็กต์ Wrapper ใหม่สำหรับการใช้งานแต่ละครั้ง
- ไวยากรณ์ที่มีขอบเขตบริบทไม่ทำงานอีกต่อไปหากคลาส type มีพารามิเตอร์หลายประเภท จินตนาการฉันต้องการที่จะหาจำนวนสิ่งที่ไม่เพียง แต่มีจำนวนเต็ม
T
แต่มีค่าบางประเภททั่วไป ฉันต้องการสร้างคลาสประเภทQuantified[A,T]
การแปลงโดยปริยาย
- เนื่องจากฉันสร้างวัตถุใหม่ฉันสามารถแคชค่าที่นั่นหรือคำนวณการแสดงที่ดีกว่า แต่ฉันควรหลีกเลี่ยงสิ่งนี้เนื่องจากอาจเกิดขึ้นหลายครั้งและการแปลงที่ชัดเจนอาจถูกเรียกใช้เพียงครั้งเดียว
สิ่งที่ฉันคาดหวังจากคำตอบ
นำเสนอกรณีการใช้งานหนึ่ง (หรือมากกว่า) ที่ความแตกต่างระหว่างแนวคิดทั้งสองมีความสำคัญและอธิบายว่าเหตุใดฉันจึงชอบอีกแบบหนึ่ง นอกจากนี้การอธิบายสาระสำคัญของทั้งสองแนวคิดและความสัมพันธ์ซึ่งกันและกันก็เป็นเรื่องที่ดีแม้ว่าจะไม่มีตัวอย่างก็ตาม