2012-03-07 10 views
6

Oto uproszczenie tego, co napotkałem. To kompiluje:Implicity i kolejność deklaracji

trait A { implicit val x = 1 } 
trait B extends A { val y = implicitly[Int] } 

Chociaż nie robić (nie mógł znaleźć wartość niejawny):

trait B extends A { val y = implicitly[Int] } 
trait A { implicit val x = 1 } 

Starałem się uczynić moje intencje jasne, określając siebie-Type: trait A { this: B => ... }, ale bezskutecznie .

Jak radzić sobie z tego rodzaju zależnościami bez martwienia się o to, w jaki sposób mój kod jest układany?

Odpowiedz

11

Musisz zadeklarować typ wyraźnie, przynajmniej na tym ostatnim

trait B extends A { val y = implicitly[Int] } 
trait A { implicit val x : Int = 1 } 

Zasady niejawny widoczność jest różny, czy jego typ jest zadeklarowana jawnie, czy nie. Jeśli tak nie jest, ukryty jest dostępny (jako domyślny) tylko po punkcie deklaracji.

Powód jest taki, że wnioskowanie o typie może stać się zbyt trudne, jeśli typ nie został zadeklarowany (jak w procedurze rekursywnej). W wielu przypadkach wnioskowanie byłoby łatwe (jak w twoim kodzie), ale specyfikacja musi być jednoznaczna.

+0

Co z ukrytymi obiektami? Czy możesz wskazać mi części specyfikacji dotyczące rozdzielczości implicitów? 'cecha X; cecha B rozszerza A {val y = niejawnie [X]}; cecha {niejawny obiekt x rozszerza X} ' – elbowich

+1

Przepraszamy za późną odpowiedź. Po bardziej pobieżnym spojrzeniu w specyfikację nie mogłem znaleźć reguły. Wspomina się jednak, że w [tym raporcie o błędzie] (https://issues.scala-lang.org/browse/SI-801) wygląda to tak, jak robi to implementacja, ale jeszcze nie dotarło do specyfikacji. Nie rozumiem, dlaczego nie powinien działać z niejawnym obiektem. –

Powiązane problemy