เหล่านี้เรียกว่าทั่วไป จำกัด พวกเขาอนุญาตให้คุณจากภายในคลาสที่กำหนดพารามิเตอร์หรือลักษณะเฉพาะเพื่อจำกัดพารามิเตอร์ประเภทใดประเภทหนึ่ง นี่คือตัวอย่าง:
case class Foo[A](a:A) { // 'A' can be substituted with any type
// getStringLength can only be used if this is a Foo[String]
def getStringLength(implicit evidence: A =:= String) = a.length
}
อาร์กิวเมนต์นัยevidence
ที่จัดจำหน่ายโดยคอมไพเลอร์, IFF คือA
String
คุณอาจจะคิดว่ามันเป็นหลักฐานที่A
จะString
โต้แย้ง --the ตัวเองไม่ได้มีความสำคัญเพียงรู้ว่ามันมีอยู่ [แก้ไข: ดีจริง ๆ แล้วมันมีความสำคัญทางเทคนิคเพราะมันหมายถึงการแปลงโดยปริยายจากA
เป็นString
ซึ่งเป็นสิ่งที่ช่วยให้คุณสามารถโทรa.length
และไม่มีคอมไพล์ตะโกนใส่คุณ]
ตอนนี้ฉันสามารถใช้มันอย่างนั้น:
scala> Foo("blah").getStringLength
res6: Int = 4
แต่ถ้าฉันลองใช้กับFoo
สิ่งที่บรรจุสิ่งอื่นที่ไม่ใช่String
:
scala> Foo(123).getStringLength
<console>:9: error: could not find implicit value for parameter evidence: =:=[Int,String]
คุณสามารถอ่านข้อผิดพลาดว่า "ไม่สามารถหาหลักฐานว่า Int == String" ... นั่นเป็นไปตามที่ควรจะเป็น! getStringLength
กำลังกำหนดข้อ จำกัด เพิ่มเติมเกี่ยวกับประเภทของA
สิ่งที่เกินความFoo
ต้องการโดยทั่วไป คือคุณจะสามารถเรียกใช้บนgetStringLength
Foo[String]
ข้อ จำกัด นี้มีการบังคับใช้ในเวลารวบรวมซึ่งยอดเยี่ยม!
<:<
และ<%<
ทำงานในทำนองเดียวกัน แต่มีการเปลี่ยนแปลงเล็กน้อย:
A =:= B
หมายถึง A จะต้องเป็น B อย่างแน่นอน
A <:< B
หมายถึง A จะต้องเป็นชนิดย่อยของ B (คล้ายกับข้อ จำกัด ประเภทแบบง่าย<:
)
A <%< B
หมายถึง A ต้องสามารถดูได้เป็น B อาจผ่านการแปลงแบบนัย (คล้ายกับข้อ จำกัด ประเภทแบบง่าย<%
)
ตัวอย่างนี้โดย @retronym เป็นคำอธิบายที่ดีเกี่ยวกับวิธีการเรียงลำดับของสิ่งที่เคยประสบความสำเร็จและข้อ จำกัด ประเภททั่วไปทำให้ง่ายขึ้นในขณะนี้
ภาคผนวก
ในการตอบคำถามติดตามผลของคุณตัวอย่างที่ฉันให้นั้นเป็นสิ่งที่ถูกจัดทำขึ้นและไม่มีประโยชน์ชัดเจน แต่ลองจินตนาการว่าใช้มันเพื่อนิยามบางอย่างเช่นList.sumInts
เมธอดซึ่งรวมรายการของจำนวนเต็ม คุณไม่ต้องการที่จะอนุญาตให้วิธีนี้จะเรียกในเก่า ๆเพียงList
List[Int]
อย่างไรก็ตามตัวList
สร้างประเภทไม่สามารถถูก จำกัด ได้ คุณยังต้องการที่จะมีรายการของสตริง foos บาร์และ whatnots ดังนั้นโดยการวางข้อ จำกัด ประเภททั่วไปบนsumInts
คุณสามารถมั่นใจได้ว่าเพียงแค่ว่าวิธีมีข้อ จำกัด List[Int]
เพิ่มเติมว่ามันสามารถนำมาใช้ใน โดยพื้นฐานแล้วคุณกำลังเขียนรหัสตัวพิมพ์พิเศษสำหรับรายการบางประเภท