Tôi đã cố gắng nắm bắt các tham số ngầm định hoạt động như thế nào trong Scala. Theo như tôi có thể nói, độ phân giải tham số ngầm sẽ diễn ra như sau:Vals lười biếng và các thông số tiềm ẩn trong Scala
- Truyền đạt đối tượng một cách rõ ràng.
- xác định ngầm định được xác định trong phạm vi.
- đối tượng Companion của lớp được sử dụng như một tham số ngầm
Tuy nhiên, khi tôi bắt đầu chơi xung quanh với điều này kết hợp Vals lười biếng tôi có một chút của một supprise. Có vẻ như những người lười biếng lười biếng chỉ sử dụng quy tắc giải quyết cuối cùng. Dưới đây là một số mẫu mã để minh họa:
class Bar(val name:String)
object Bar { implicit def bar = new Bar("some default bar") }
class Foo {
lazy val list = initialize
def initialize(implicit f:Bar) = {
println("initialize called with Bar: '" + f.name + "' ...")
List[Int]()
}
}
trait NonDefaultBar extends Foo {
implicit def f = new Bar("mixed in implicit bar")
def mixedInInit = initialize
lazy val mixedInList = list
}
object Test {
def test = {
println("Case 1: with implicitp parameter from companion object")
val foo1 = new Foo
foo1.list
foo1.initialize
println("Case 2: with mixedin implicit parameter overriding the default one...")
val foo2 = new Foo with NonDefaultBar
foo2.mixedInList
val foo3 = new Foo with NonDefaultBar
foo3.mixedInInit
println("Case 3: with local implicit parameter overriding the default one...")
implicit def nonDefaultBar = new Bar("locally scoped implicit bar")
val foo4 = new Foo
foo4.list
foo4.initialize
}
}
Calling Test.test
cho đầu ra sau đây:
Case 1: with implicitp parameter from companion object
initialize called with Bar: 'some default bar' ...
initialize called with Bar: 'some default bar' ...
Case 2: with mixedin implicit parameter overriding the default one...
initialize called with Bar: 'some default bar' ...
initialize called with Bar: 'mixed in implicit bar'...
Case 3: with local implicit parameter overriding the default one...
initialize called with Bar: 'some default bar' ...
initialize called with Bar: 'locally scoped implicit bar' ...
Tại sao trình biên dịch không bắt rằng có một Bar implict trộn lẫn trong khi gọi mixedInList trong trường hợp 2. Trong trường hợp 3 nó cũng bỏ qua thanh địa chỉ được xác định cục bộ khi truy cập vào danh sách.
Có cách nào để sử dụng các tham số ngầm với vals lười không sử dụng ngầm định được xác định trong đối tượng đồng hành không?
Ok, nhưng * không * nó nhận ra sự liên quan? Họ được biết đến tại compiletime phải không? Có lẽ nó sẽ làm việc nếu tôi di chuyển các tham số tiềm ẩn để các nhà xây dựng? –
Nó nhận ra Thanh chỉ tiềm ẩn nằm trong phạm vi thời gian biên dịch, và đó là một trong thanh đồng hành. Bởi vì 'list' chỉ được định nghĩa trên' Foo', nó sẽ luôn luôn sử dụng cái này. Bạn có thể định nghĩa ngầm định trong hàm tạo của bạn, nhưng ngầm định trong đặc điểm sẽ vẫn không nằm trong phạm vi, vì nó chỉ tồn tại trên cá thể. – drexin
Vì vậy, nếu tôi di chuyển phương thức val và khởi tạo lazy sang đặc điểm 'NonDefaultBar' và để cho đặc điểm đó mở rộng' Foo' và cũng di chuyển def deficit sang 'Foo', thì trình biên dịch sẽ biết lấy def deficit trong' Foo 'khi đánh giá 'danh sách val lười biếng'? –