Ten prosty test, oczywiście, działa zgodnie z oczekiwaniami:Scala stawia pierwszeństwo niejawnej konwersji na "naturalne" operacje ... Dlaczego? Czy to błąd? Czy robię coś złego?
scala> var b = 2 b: Int = 2 scala> b += 1 scala> b res3: Int = 3
Teraz przynieść to w zakresie:
class A(var x: Int) { def +=(y:Int) { this.x += y } } implicit def int2A(i:Int) : A = new A(i)
jestem definiowania nowej klasy i + = praca na nim, i wygodna niejawna konwersja dla tych czasów, kiedy chcę dodać wartość Int do A Int.
Nigdy się nie spodziewałem, że to wpłynie na sposób, w jaki zachowują się moje zwykłe operacje Int, kiedy klasa "A" wcale nie jest częścią wyrażenia.
Ale robi:
scala> var b:Int = 0 b: Int = 0 scala> b += 1 scala> b res29: Int = 0 scala> b += 2 scala> b res31: Int = 0
Co wydaje się być tutaj dzieje jest to, że b: int jest niejawnie konwertowane do klasy „A”, który nie jest związany z żadną zmienną, a następnie + = jest wywoływany na nim, odrzucając wyniki.
Scala wydaje się dawać wysoki priorytet niejawnej konwersji ponad naturalnym + = zachowaniem (magia kompilatora, a nie faktyczna metoda), która jest już zdefiniowana jako Ints. Zdrowy rozsądek jak również tło w języku C++ mówi mi, że implicite należy wywoływać tylko w ostateczności, gdy kompilacja w przeciwnym razie byłaby nieudana. To prowadzi do wielu pytań ...
- Dlaczego? Czy to błąd? Czy to projekt?
- Czy istnieje obejście (inne niż niewykorzystywanie "+ =" dla operacji "+ =" mojego DSL)?
Dzięki
'scala -Xprint: typer' mówi mi, że robi dokładnie to, co powiedziałeś - używając niejawnej konwersji, aby mogła wywołać' + = '. –