Как применить интерполяцию Scala String для переменной? [Дубликат]

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

body:contains-selector(a.active) { background: red; }

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

Эта статья Почему у нас нет родительского селектора , это подробно объясняет.

42
задан Suma 3 November 2016 в 11:19
поделиться

4 ответа

s - фактически метод на StringContext (или то, что может быть неявно преобразовано из StringContext). Когда вы пишете

whatever"Here is text $identifier and more text"

, компилятор записывает его в

StringContext("Here is text ", " and more text").whatever(identifier)

По умолчанию StringContext дает вам методы s, f и raw * .

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

Однако вы можете использовать vars, чтобы вы могли менять значения что ты хочешь. И метод по умолчанию s просто вызывает toString (как и следовало ожидать), чтобы вы могли играть в такие игры, как

class PrintCounter {
  var i = 0
  override def toString = { val ans = i.toString; i += 1; ans }
}

val pc = new PrintCounter
def pr[A](a: A) { println(s"$pc: $a") }
scala> List("salmon","herring").foreach(pr)
1: salmon
2: herring

(0 уже был вызван REPL в этом примере).

Это самое лучшее, что вы можете сделать.

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

31
ответ дан Elnur Abdurrakhimov 18 August 2018 в 01:56
поделиться
  • 1
    Одно небольшое дополнение. Может использоваться не только идентификатор. Любое допустимое выражение scala может быть помещено между $ {}. – pedrofurla 26 July 2013 в 09:31

Вот возможное решение # 1 в контексте исходного вопроса, основанного на превосходном ответе Рекса

val name = "World"                  //> name: String = World
val template = name=>s"Hello $name" //> template: Seq[Any]=>String = <function1>
val message = template(name)        //> message: String = Hello World
10
ответ дан Eran Medan 18 August 2018 в 01:56
поделиться
  • 1
    С помощью Scala 2.11.5 вторая строка дает ошибку «отсутствие имени типа параметра». Я думаю, что это должно быть написано как val template = (name:Any)=>s"Hello $name" или def template(name:Any) = s"Hello $name" – Suma 2 March 2015 в 09:49
  • 2
    вы добавили val name = "World" раньше? Я думаю, что это помогает выводам типа, и без него вам действительно нужно будет указать тип имени ... другими словами, я не знаю, затеняет ли имя $ имя параметра или нет ... – Eran Medan 2 March 2015 в 17:47
  • 3
    Я вложил все три строки в источник Scala. Я не могу скомпилировать его, если я не добавлю аннотацию типа к параметру имени. – Suma 2 March 2015 в 18:46
  • 4
    Хм ... Наверное, это была ошибка в 2.10 или что-то ... хорошая добыча! – Eran Medan 3 March 2015 в 04:27

Это неотъемлемо невозможно в текущей реализации: имена локальных переменных недоступны во время выполнения - могут храниться как символы отладки, но также могут быть удалены. (Имена переменных-членов, но это не то, что вы здесь описываете).

1
ответ дан jsalvata 18 August 2018 в 01:56
поделиться
  1. Интерполяция строк происходит во время компиляции, поэтому компилятор обычно не имеет достаточной информации для интерполяции s(str). Он ожидает строковый литерал в соответствии с SIP .
  2. В разделе Advanced Usage в документации, которую вы связываете, объясняется, что выражение формы id"Hello $name ." переводится во время компиляции в new StringContext("Hello", "."). id(name).

Обратите внимание, что id может быть определяемым пользователем интерполятором, введенным через неявный класс. В документации приведен пример интерполятора json,

implicit class JsonHelper(val sc: StringContext) extends AnyVal {
  def json(args: Any*): JSONObject = {
    ...
  }
}
7
ответ дан Kipton Barros 18 August 2018 в 01:56
поделиться
Другие вопросы по тегам:

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