Подтвердить что ты не робот

Необходимость уточнения в Scala литеральных идентификаторах (backticks)

Чтение программирования в Scala 2nd Ed и я натолкнулись на это:

литеральный идентификатор "Идея состоит в том, что вы можете поместить любую строку, принятую во время выполнения, как идентификатор между обратным ходом"

Я не совсем уверен, почему я буду использовать это? Книга привела пример использования метода статического урока в классе Java Thread.

Итак, поскольку в Scala выход является резервным словом, если я использую доходность с обратными окнами,

Thread.`yield`()

он проигнорировал бы выход Scala и дал бы мне доступ к уроку метода класса Java Thread вместо этого?

Спасибо заранее.

4b9b3361

Ответ 1

Совершенно верно. Используя обратные выходы, вы можете более или менее дать какое-либо имя идентификатору поля. На самом деле вы даже можете сказать

val ` ` = 0

который определяет переменную с именем (один символ пробела).

Литеральное определение идентификаторов полезно в двух случаях. В первом случае, когда в Scala уже зарезервировано одно слово с именем Scala, и вам нужно использовать библиотеку Java, которая не заботится об этом (и, конечно же, почему она должна).

В другом случае используется оператор case. Соглашение состоит в том, что имена нижних регистров относятся к переменным соответствия, тогда как имена верхнего регистра относятся к идентификаторам из внешней области. Таким образом,

val A = "a"
val b = "b"
"a" match {
  case b => println("b")
  case A => println("A")
}

prints "b" (если компилятор был достаточно тупым, чтобы не терпеть неудачу, сказав, что case A были недоступны). Если вы хотите обратиться к первоначально определенному val b, вам нужно использовать обратные ссылки в качестве маркера.

"a" match {
  case `b` => println("b")
  case A => println("A")
}

Что печатает "A".

Добавить. В этом недавнем вопросе есть более продвинутый вариант использования с угловыми скобками (< gt;), где обратные ссылки были необходимо, чтобы компилятор переваривал код для метода setter (который сам по себе использует некоторый "магический синтаксис" ).

Ответ 2

Спасибо @Debilski, это помогает мне понять этот код ниже из документа AKKA:

class WatchActor extends Actor {
    val child = context.actorOf(Props.empty, "child")
    ...
    def receive = {
        ...
        case Terminated(`child`) ⇒ ...
    }
}

Случай:

case Terminated(`child`)

совпадает с сообщением типа Terminated with ActorRef, которое равно дочернему, которое определено ранее.

С помощью этого утверждения:

case Terminated(c)

Мы сопоставляем каждое завершенное сообщение с любой ссылкой ActorRef, отображаемой в c.