Нет родительского селектора; так же, как нет предыдущего селектора. Одна из веских причин не иметь этих селекторов заключается в том, что браузер должен пройти через всех дочерних элементов элемента, чтобы определить, следует ли применять класс. Например, если вы написали:
body:contains-selector(a.active) { background: red; }
Затем браузеру придется подождать, пока он не загрузится, и все разобрались до
, чтобы определить, должна ли страница быть красной или нет.
Эта статья Почему у нас нет родительского селектора , это подробно объясняет.
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 не выйдет, или посмотрите исходный код и не определите свой собственный. По умолчанию, нет обработки отхода, поэтому определение вашего собственного довольно легко.
Вот возможное решение # 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
val template = (name:Any)=>s"Hello $name"
или def template(name:Any) = s"Hello $name"
– Suma
2 March 2015 в 09:49
val name = "World"
раньше? Я думаю, что это помогает выводам типа, и без него вам действительно нужно будет указать тип имени ... другими словами, я не знаю, затеняет ли имя $ имя параметра или нет ...
– Eran Medan
2 March 2015 в 17:47
Это неотъемлемо невозможно в текущей реализации: имена локальных переменных недоступны во время выполнения - могут храниться как символы отладки, но также могут быть удалены. (Имена переменных-членов, но это не то, что вы здесь описываете).
s(str)
. Он ожидает строковый литерал в соответствии с SIP . id"Hello $name ."
переводится во время компиляции в new StringContext("Hello", "."). id(name)
. Обратите внимание, что id
может быть определяемым пользователем интерполятором, введенным через неявный класс. В документации приведен пример интерполятора json
,
implicit class JsonHelper(val sc: StringContext) extends AnyVal {
def json(args: Any*): JSONObject = {
...
}
}