Ta odpowiedź jest 2 lata późno, nadal fo z korzyścią dla innych Chciałbym zaznaczyć, że zaakceptowana odpowiedź niepotrzebnie rozciąga się od AnyVal.
Istnieje tylko niewielki błąd, który należy poprawić w oryginalnej odpowiedzi. Metoda def **
wymaga tylko jednego parametru, tj. Wykładnik jako podstawa jest już przekazywany w konstruktorze, a nie w dwóch, tak jak w oryginalnym kodzie. Ustalające, że i usuwanie wyników backticks w:
import scala.math.pow
implicit class PowerInt(i: Int) {
def ** (b: Int): Int = pow(i, b).intValue
}
który działa zgodnie z oczekiwaniami, jak widać here.
Scala kompilator będzie rzutować Int
Do PowerInt
tylko jeśli metoda, która jest wywoływana na nim jest niezdefiniowany. Dlatego nie musisz przedłużać z AnyVal.
Scala szuka za kulisami niejawnej klasy, której typ argumentu konstruktora jest taki sam, jak typ rzutowanego obiektu. Ponieważ obiekt może mieć tylko jeden typ, niejawne klasy nie mogą mieć więcej niż jeden argument w swoim konstruktorze. Ponadto, jeśli zdefiniujesz dwie niejawne klasy o tym samym typie konstruktora, upewnij się, że ich funkcje mają unikatowe podpisy, w przeciwnym razie Scala nie będzie wiedziała, do której klasy należy rzucać, i będzie narzekać na niejasności.
Zauważ, że '**' ani '^' nie będzie miał prawo pierwszeństwa (to jest powód, dlaczego stdlib nie obejmuje tego). '4 * 5 ** 3' to' (4 * 5) ** 3', a nie '4 * (5 ** 3)'. – sschaef
Scala może zmienić ich metody analizowania na gramatykę inną niż LL (1); np .: zobacz, jak C++ obsługuje wiele '>' '<' deterministycznie –