Как отменить импорт оператора String + в Scala?

Я пишу DSL, где оператор «+» строго числовой, как и в некоторых других популярных языках. Это близко, но оператор String "+" портит мои неявные преобразования. Какой синтаксис отменяет импорт оператора класса String?

Для большей ясности вместо этого:

scala> var x = "2" + 3;
x: java.lang.String = 23

Я бы хотел получить x: Int = 5

Думаю, для этого мне нужны всего две вещи:

  • Удалите (не импортируйте в мою область) определение "+" из строк
  • Определите неявное преобразование String в Int

Я застрял на первом шаге.

Спасибо


person Alex R    schedule 18.04.2010    source источник
comment
Я полагаю, что import scala.Predef. {Any2stringadd = ›_} будет работать. Но это не так. Должно быть, я что-то пропустил.   -  person Eastsun    schedule 19.04.2010
comment
any2stringadd используется там, где левая часть не поддерживает оператор +, но правая часть представляет собой строку. (Чтобы увидеть это в действии, запустите scala -Xprint:typer и выполните new Object + "ZZZZZ") Напротив, "ZZZZZ" + new Object может использовать оператор +, который уже определен в String, поэтому any2stringadd не используется.   -  person Ken Bloom    schedule 19.04.2010


Ответы (3)


Согласно разделу 12.3.1 спецификации Scala, метод + for String имеет особую обработку компилятором. Я не знаю наверняка, но я думаю, что это означает, что вы не можете «отменить импорт», что очень досадно, потому что это действительно нарушает систему типов (как и связанный с ним метод toString).

Не могли бы вы использовать другое имя для оператора в вашем DSL, например ++ или &?

person Kristian Domagala    schedule 18.04.2010
comment
Тот факт, что компилятор уделяет особое внимание методу +, не имеет ничего общего с тем, можно ли его импортировать или нет. Язык должен быть очень ортагональным и обрабатывать все методы класса семантически одинаково, независимо от того, синтезированы ли они компилятором или предоставлены библиотекой времени выполнения. - person Ken Bloom; 19.04.2010
comment
Я бы согласился с тем, что вы говорите, если + действительно был явно указан в классе String, но спецификация только намекает на это, и IMO можно интерпретировать как указание на то, что существует неявное преобразование (которое встроено в компилятор и, следовательно, может 'не быть неимпортированным) к какому-либо типу (например, StringAdd), что позволяет клиентам обрабатывать String, как если бы он был определен с помощью метода +. Я счастлив, что здесь оказался неправ, но даже благодаря отражению времени выполнения на StringRichString) я не могу найти метод + (т.е. $plus). - person Kristian Domagala; 21.04.2010
comment
Спасибо, звучит как еще один случай магии компилятора, которая фактически нарушает ортогональность и неожиданно взаимодействует с другими языковыми функциями и библиотеками. - person Alex R; 23.04.2010
comment
Да, я не уверен, почему это нельзя было реализовать так же, как Predef.any2stringadd, например Predef.string2stringadd:String => StringAdd. - person Kristian Domagala; 23.04.2010
comment
В современном Scala можно отменить импорт String и использовать настраиваемый интерполятор для создания настраиваемого типа. В настоящее время невозможно предоставить собственный пустой интерполятор для синтаксиса строкового литерала. - person som-snytt; 11.01.2020

Метод + для строки является методом класса String (и, следовательно, для каждого строкового объекта), и как таковой его нельзя не импортировать.

person Ken Bloom    schedule 19.04.2010

Вы не можете отменить его импорт, но вы можете использовать +: и определить его в классе int. Было бы лучше, если бы вы написали это так: "2" .toInt + 3.

person Anonymous    schedule 10.03.2011