implicitly
ที่นี่มีไม่กี่เหตุผลที่จะใช้วิธีการที่ง่ายครื้นเครง
เพื่อทำความเข้าใจ / แก้ไขปัญหามุมมองโดยนัย
มุมมอง Implicit สามารถถูกทริกเกอร์เมื่อส่วนนำหน้าของส่วนที่เลือก (พิจารณาตัวอย่างเช่นthe.prefix.selection(args)
ไม่มีสมาชิกselection
ที่สามารถใช้งานได้args
(แม้หลังจากพยายามแปลงargs
ด้วย Implicit Views) ในกรณีนี้คอมไพเลอร์จะค้นหาสมาชิกโดยปริยาย ในขอบเขตปัจจุบันหรือขอบเขตปิดสืบทอดหรือนำเข้าซึ่งเป็นฟังก์ชันจากประเภทของประเภทนั้นthe.prefix
เป็นประเภทที่มีวิธีการที่selection
กำหนดไว้หรือเทียบเท่าโดยนัย
scala> 1.min(2) // Int doesn't have min defined, where did that come from?
res21: Int = 1
scala> implicitly[Int => { def min(i: Int): Any }]
res22: (Int) => AnyRef{def min(i: Int): Any} = <function1>
scala> res22(1) //
res23: AnyRef{def min(i: Int): Int} = 1
scala> .getClass
res24: java.lang.Class[_] = class scala.runtime.RichInt
มุมมองโดยนัยยังสามารถถูกเรียกใช้เมื่อการแสดงออกไม่สอดคล้องกับประเภทที่คาดหวังดังต่อไปนี้:
scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1
ที่นี่คอมไพเลอร์มองหาฟังก์ชั่นนี้:
scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>
การเข้าถึงพารามิเตอร์โดยปริยายที่ถูกผูกไว้กับบริบทที่แนะนำ
พารามิเตอร์โดยนัยเป็นคุณสมบัติที่สำคัญของ Scala มากกว่า Views Implicit พวกเขาสนับสนุนรูปแบบการเรียนประเภท ห้องสมุดมาตรฐานนี้ใช้ในสถานที่ไม่กี่ - ดูและวิธีการที่จะนำมาใช้ในscala.Ordering
SeqLike#sorted
พารามิเตอร์โดยนัยยังใช้เพื่อส่งรายการ Array และCanBuildFrom
อินสแตนซ์
Scala 2.8 อนุญาตให้มีการจดชวเลขไวยากรณ์สำหรับพารามิเตอร์โดยนัยที่เรียกว่าขอบเขตบริบท สั้น ๆ วิธีการที่มีพารามิเตอร์ประเภทA
ที่ต้องใช้พารามิเตอร์ประเภทM[A]
:
def foo[A](implicit ma: M[A])
สามารถเขียนใหม่เป็น:
def foo[A: M]
แต่จุดผ่านพารามิเตอร์โดยนัยคืออะไร แต่ไม่ตั้งชื่อมัน สิ่งนี้จะมีประโยชน์เมื่อใช้งานวิธีการได้foo
อย่างไร
บ่อยครั้งที่พารามิเตอร์ implicit ไม่จำเป็นต้องถูกอ้างถึงโดยตรงมันจะถูก tunneled ผ่านเป็นอาร์กิวเมนต์ implicit ไปยังเมธอดอื่นที่ถูกเรียก หากจำเป็นคุณยังคงสามารถรักษาลายเซ็นของวิธีการกระชับด้วย Context Bound และการเรียกใช้implicitly
เพื่อทำให้ค่าเป็นจริง:
def foo[A: M] = {
val ma = implicitly[M[A]]
}
ผ่านชุดย่อยของพารามิเตอร์โดยนัยอย่างชัดเจน
สมมติว่าคุณกำลังเรียกเมธอดที่พิมพ์ชื่อคนสวย ๆ โดยใช้วิธีการพิมพ์ตามประเภทคลาส:
trait Show[T] { def show(t: T): String }
object Show {
implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }
def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}
case class Person(name: String, age: Int)
object Person {
implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
}
}
val p = Person("bob", 25)
implicitly[Show[Person]].show(p)
ถ้าเราต้องการเปลี่ยนวิธีการที่ชื่อเป็นผลลัพธ์ เราอย่างชัดเจนสามารถเรียกPersonShow
อย่างชัดเจนผ่านทางเลือกแต่เราต้องการคอมไพเลอร์ที่จะผ่านShow[String]
Show[Int]
Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)