Какая языковая функция scala используется? Кажется, извлечь значения из JsObject и привести его? - PullRequest
0 голосов
/ 08 апреля 2020

Я просто читаю некоторый исходный код scala для изучения, и я пришел к этому:

Как здесь работает o str "t"? Кажется, он извлекает ключ "t" из JsObject и приводит его к строке?

  Try(Json parse str) map {
        case o: JsObject =>
          o str "t" flatMap {
            case "p" => Some(Ping(o int "l"))

Есть похожие шаблоны:

case "opening" =>
              for {
                d    <- o obj "d"
                path <- d str "path"
                fen  <- d str "fen"
                variant = dataVariant(d)
              } yield Opening(variant, Path(path), FEN(fen))

Не уверен, что o obj "d" делается? Или, что еще более важно, как это происходит?

Я не могу найти какие-либо ссылки на скаляр или значения уровня пакета, которые позволили бы это?

Ссылка: https://github.com/ornicar/lila-ws/blob/master/src/main/scala/ipc/ClientOut.scala#L112

1 Ответ

4 голосов
/ 08 апреля 2020

В выражении o obj "d" используется комбинация метода расширения через неявное преобразование и инфиксная нотация . Desugared переводится как

augment(o).str("t")

, где augment определяется как

final class LilaJsObject(private val js: JsObject) extends AnyVal {

  def str(key: String): Option[String] =
    (js \ key).asOpt[String]

  ...
}

object LilaJsObject {

  implicit def augment(o: JsObject) = new LilaJsObject(o)
}

Эту низкоуровневую реализацию метода расширения можно упростить с помощью неявного классы

implicit final class LilaJsObject(private val js: JsObject) extends AnyVal {
  def str(key: String): Option[String] =
    (js \ key).asOpt[String]
}

В Scala 3 метод расширения синтаксис становится еще проще.

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

scala -Xprint:parser -e '"Hello" charAt 2'

, который должен отображать "Hello".charAt(2). Инфиксная запись может привести к красивым DSL , например,

object repeat {
  def it(n: Int) = new {
    def times[A](f: => A): Unit = (1 to n).foreach(_ => f)
  }
}

can express на почти человеческом языке

repeat it 5 times { println("hello") }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...