Серьезен ли Одерский с "счетами! * & ^% ~ Code!"? - PullRequest
5 голосов
/ 28 апреля 2010

В своей книге «Программирование в scala» (глава 5, раздел 5.9, стр. 93) Одерский упомянул это выражение "bills !*&^%~ code!"

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

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

invoke (bills.!*&^%~(code)).!()."

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

Ответы [ 4 ]

9 голосов
/ 28 апреля 2010

Что хотел сказать Одерский, так это то, что можно было бы иметь действительный код, похожий на этот. Например, код ниже:

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.

3 голосов
/ 28 апреля 2010

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

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

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

(счета.! * & ^% ~ (код)).! ().

идентичны

bills! * & ^% ~ code!

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

2 голосов
/ 28 апреля 2010

Сочетание '. ()' Является необязательным при вызовах методов (как объяснил 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 голосов
/ 28 апреля 2010

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

bill add monkey

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

bill.add(monkey)

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

...