Tôi sẽ giải thích các trường hợp sử dụng chính của implicit dưới đây, nhưng để biết thêm chi tiết, xem relevant chapter of Programming in Scala.
thông số Implicit
Trận chung kết danh sách tham số trên một phương pháp có thể được đánh dấu implicit
, có nghĩa là giá trị này sẽ được lấy từ bối cảnh trong đó chúng được gọi. Nếu không có giá trị tiềm ẩn của đúng loại trong phạm vi, nó sẽ không biên dịch. Vì giá trị tiềm ẩn phải giải quyết cho một giá trị duy nhất và để tránh xung đột, nên tạo loại cụ thể cho mục đích của nó, ví dụ: không yêu cầu các phương pháp của bạn để tìm kiếm một ẩn số Int
!
dụ:
// probably in a library
class Prefixer(val prefix: String)
def addPrefix(s: String)(implicit p: Prefixer) = p.prefix + s
// then probably in your application
implicit val myImplicitPrefixer = new Prefixer("***")
addPrefix("abc") // returns "***abc"
chuyển đổi Implicit
Khi trình biên dịch tìm thấy một biểu hiện của loại sai cho bối cảnh, nó sẽ tìm kiếm một giá trị tiềm ẩn Function
của một loại mà sẽ cho phép nó để đánh máy. Vì vậy, nếu yêu cầu A
và nó tìm thấy một B
, nó sẽ tìm kiếm một giá trị tiềm ẩn thuộc loại B => A
trong phạm vi (nó cũng kiểm tra một số địa điểm khác như trong các đối tượng đồng hành B
và A
, nếu chúng tồn tại). Vì def
s có thể được "mở rộng eta" thành các đối tượng Function
, một implicit def xyz(arg: B): A
cũng sẽ hoạt động.
Vì vậy, sự khác biệt giữa các phương pháp của bạn là phương pháp được đánh dấu implicit
sẽ được trình biên dịch đưa vào cho bạn khi một số Double
được tìm thấy nhưng yêu cầu Int
.
implicit def doubleToInt(d: Double) = d.toInt
val x: Int = 42.0
sẽ làm việc giống như
def doubleToInt(d: Double) = d.toInt
val x: Int = doubleToInt(42.0)
Trong thứ hai chúng tôi đã chèn chuyển đổi bằng tay; trong trình biên dịch đầu tiên cũng tự động làm như vậy. Chuyển đổi là bắt buộc vì chú thích loại ở phía bên tay trái.
Về đoạn đầu tiên của bạn từ Play:
Hoạt động được giải thích trên this page từ tài liệu Phát (xem thêm API docs). Bạn đang sử dụng
apply(block: (Request[AnyContent]) ⇒ Result): Action[AnyContent]
đối tượng Action
(là đồng hành với đặc điểm cùng tên).
Vì vậy, chúng ta cần phải cung cấp một chức năng như là đối số, mà có thể được viết như một chữ theo hình thức
request => ...
Trong một hàm nghĩa đen, phần trước =>
là một tuyên bố giá trị, và có thể được đánh dấu implicit
nếu bạn muốn, giống như trong bất kỳ tuyên bố khác val
nào. Ở đây, request
không phải được đánh dấu implicit
để làm điều này để kiểm tra, nhưng bằng cách làm như vậy nó sẽ là sẵn có dưới dạng giá trị ẩn cho bất kỳ phương pháp nào có thể cần nó trong hàm (và tất nhiên, nó có thể cũng được sử dụng một cách rõ ràng). Trong trường hợp cụ thể này, điều này đã được thực hiện vì phương thức bindFromRequest
trên lớp Form yêu cầu đối số ngụ ý Request
.
Cảm ơn bạn đã phản hồi. Liên kết cho chương 21 thực sự tuyệt vời. Cảm kích điều đó. – Clive
Chỉ cần thêm phần này, video sau đây sẽ giải thích rõ ràng về các mối liên hệ với một số tính năng khác của scala http://www.youtube.com/watch?v=IobLWVuD-CQ – Shakti