Odersky серьезный со “счетами! % *&^ ~ код!”?

В его книжном программировании в scala (Раздел Главы 5 5,9 Pg 93) Odersky упомянул это выражение"bills !*&^%~ code!"

В сноске на той же странице:

"К настоящему времени необходимо смочь выяснить, что, учитывая этот код, компилятор Scala был бы

вызвать (bills.!*&^%~(code)).!()."

Это немного к загадочному для меня, кто-то мог объяснить, что продолжается здесь?

5
задан Daniel C. Sobral 28 April 2010 в 07:08
поделиться

4 ответа

Одерский имеет в виду, что вполне возможно иметь действительный код, выглядящий вот так. Например, код ниже:

class BadCode(whose: String, source: String) {
  def ! = println(whose+", what the hell do you mean by '"+source+"'???")
}

class Programmer(who: String) {
  def !*&^%~(source: String) = new BadCode(who, source)
}

val bills = new Programmer("Bill")
val code = "def !*&^%~(source: String) = new BadCode(who, source)"
bills !*&^%~ code!

Просто скопируйте и вставьте его в REPL.

9
ответ дан 18 December 2019 в 10:42
поделиться

Точка необязательна для вызова метода, который принимает один параметр или имеет пустой список параметров.

При использовании этой функции предполагается, что следующий фрагмент после пробела, следующий за именем метода, является единственным параметром.

Следовательно,

(bills.! * & ^% ~ (Code)).! ().

идентичен счету

! * & ^% ~ Code!

Второй восклицательный знак вызывает метод для возвращаемого значения из первого вызова метода.

3
ответ дан 18 December 2019 в 10:42
поделиться

Я не уверен, предоставляет ли книга сигнатуры методов, но я предполагаю, что это просто комментарий к синтаксическому сахару Scala, поэтому предполагается, что если вы наберете:

bill add monkey

где есть объект bill, у которого есть метод add, который принимает параметр, а затем автоматически интерпретирует его как:

bill.add(monkey)

Будучи немного ржавым Scala, я не совсем уверен, как он разбивает код! в (code).! (), за исключением неопределенного щекотания серых ячеек, которые символ! Оператор используется для запуска актера, который в терминах компилятора может быть интерпретирован как неявный метод.! () объекта.

2
ответ дан 18 December 2019 в 10:42
поделиться

Комбинация ". ()", Являющаяся необязательной, с вызовами методов (как Wysawyg объяснил выше) и возможность использовать (почти) любые символы, которые вам нравятся для именования методов позволяет писать методы на Scala, которые выглядят как перегрузка оператора. Вы даже можете изобрести собственных операторов.

Например, у меня есть программа, которая занимается компьютерной 3D-графикой. У меня есть собственный класс Vector для представления трехмерного вектора:

class Vector(val x: Double, val y: Double, val z: Double) {
    def +(v: Vector) = new Vector(x + v.x, y + v.y, z + v.z)

    // ...etc.
}

Я также определил метод ** (не показан выше) для вычисления перекрестного произведения двух векторов. Очень удобно, что вы можете создавать свои собственные операторы, подобные этому в Scala, не многие другие языки программирования обладают такой гибкостью.

2
ответ дан 18 December 2019 в 10:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: