2013-03-19 33 views
6

Tôi đang bối rối bởi mô tả này trong "5.1.3 Độ phân giải Implicit" trong cuốn sách Giô-suê Suareth của Scala trong chiều sâu, trên trang 100:implicits cho các đối tượng trong Scala

Scala đối tượng không thể có bạn đồng hành các đối tượng cho liên quan. Bởi vì điều này, hàm ý liên quan đến loại đối tượng, được mong muốn trên phạm vi tiềm ẩn của loại đối tượng đó, phải được cung cấp từ phạm vi bên ngoài . Dưới đây là một ví dụ:

scala> object Foo { 
    | object Bar { override def toString = "Bar" } 
    | implicit def b : Bar.type = Bar 
    |} 
defined module Foo 
scala> implicitly[Foo.Bar.type] 
res1: Foo.Bar.type = Bar 

Nhưng trong khi tôi làm đối tượng Bar ngầm trong REPL:

scala> object Foo { 
    | implicit object Bar { 
    |  override def toString = "isBar" } 
    | } 
defined module Foo 
scala> implicitly[Foo.Bar.type] 
res0: Foo.Bar.type = isBar 

Dường như nó không cần phải xác định một ngầm trong phạm vi bên ngoài. Hay tôi có ý nghĩa của Joshua hoàn toàn sai?

+1

Khi nào cuốn sách được viết và bạn đang sử dụng phiên bản Scala nào? Điều này có thể đã thay đổi một chút trong 2,9 hoặc 2,10. – KChaloux

+1

Mọi thứ như trong câu trả lời của tôi ít nhất là từ 2.9.x trở lên. Josh chắc hẳn đã đề cập đến Scala trước 2.9, hoặc không biết gì về ngữ nghĩa. FTR Tôi đã rất ngạc nhiên và vui mừng khi tôi phát hiện ra rằng điều này là có thể. –

+0

Cảm ơn bạn đã trả lời. Nó được đề xuất trong cuốn sách này bao gồm 2.7.x đến 2.9.x. Tôi có 2,10 được cài đặt trên máy tính của tôi có thể hoạt động khác nhau. – cfchou

Trả lời

8

Trong tình huống này các đối tượng hành động như thể họ là bạn đồng hành của mình, vì vậy bạn chỉ cần tổ của đối tượng kiểu nhắc implicits trong cơ thể của đối tượng chính nó,

scala> object Bar { 
    | override def toString = "Bar" 
    | implicit def b : Bar.type = Bar 
    | } 
defined module Bar 

scala> implicitly[Bar.type] 
res0: Bar.type = Bar 

Lưu ý rằng đây cơ thể của Bar đã được coi là một phần của phạm vi tiềm ẩn để giải quyết Bar.type.

Đây có thể là một góc tối nghĩa của hệ thống loại Scala, nhưng tôi đã có thể sử dụng nó ở chế độ mã hóa shapeless của polymorphic (function) values.

2

Nếu bạn đặt đoạn mã sau vào một tập tin và thử biên dịch sử dụng scalac nó không thành công với một 'implicit' modifier cannot be used for top-level objects

implicit object Foo { 
    object Bar { override def toString = "Bar" } 
} 

Tuy nhiên điều này biên dịch tốt:

object Foo { 
    implicit object Bar { override def toString = "Bar" } 
} 

Tôi tin rằng bằng cách sử dụng REPLimplicit's là không chính xác ở mức cao nhất do đó dường như không nhất quán.