Это вносит шум (примечание: в 2.10, в 2.11 и выше вы просто объявляете val закрытым). Вы не всегда хотите. Но так оно и есть на данный момент.
Вы не можете обойти эту проблему, следуя шаблону private-value-class, потому что компилятор на самом деле не может видеть, что это класс значения в конце, поэтому он идет по общему маршруту. Вот байт-код:
12: invokevirtual #24;
//Method Definition$.IntOps:(I)LDefinition$IntOps;
15: invokeinterface #30, 1;
//InterfaceMethod Definition$IntOps.squared:()I
Видите, как первый возвращает копию класса Definition$IntOps
? Это в коробке.
Но эти два шаблона работают, вроде:
(1) Общий шаблон имени.
implicit class RichInt(val repr: Int) extends AnyVal { ... }
implicit class RichInt(val underlying: Int) extends AnyVal { ... }
Используйте один из них. Добавление i
в качестве метода раздражает. Добавление underlying
, когда ничего не лежит в основе, не так уж плохо — вы нажмете его, только если вы все равно пытаетесь получить базовое значение. И если вы продолжаете использовать одно и то же имя снова и снова:
implicit class RicherInt(val repr: Int) extends AnyVal { def sq = repr * repr }
implicit class RichestInt(val repr: Int) extends AnyVal { def cu = repr * repr * repr }
scala> scala> 3.cu
res5: Int = 27
scala> 3.repr
<console>:10: error: type mismatch;
found : Int(3)
required: ?{def repr: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method RicherInt of type (repr: Int)RicherInt
and method RichestInt of type (repr: Int)RichestInt
коллизия имен решает вашу проблему в любом случае. Если вы действительно хотите, вы можете создать пустой класс значений, который существует только для того, чтобы сталкиваться с repr
.
(2) Явный неявный шаблон
Иногда вы внутренне хотите, чтобы ваше значение называлось как-то короче или более мнемонично, чем repr
или underlying
, не делая его доступным для исходного типа. Один из вариантов — создать неявную пересылку следующим образом:
class IntWithPowers(val i: Int) extends AnyVal {
def sq = i*i
def cu = i*i*i
}
implicit class EnableIntPowers(val repr: Int) extends AnyVal {
def pow = new IntWithPowers(repr)
}
Теперь вам нужно вызывать 3.pow.sq
вместо 3.sq
— что может быть хорошим способом разделить ваше пространство имен! — и вам не нужно беспокоиться о загрязнении пространства имен за пределами исходного repr
.
person
Rex Kerr
schedule
30.07.2013
private
или потеряйте квалификатор, но, видимо, это не разрешено для классов значений. Поэтому я думаю, что ответ таков: вы не можете. - person Tobias Brandt   schedule 30.07.20134.i.i.i.i.i.i
- person nilskp   schedule 30.07.2013