Как вставить двойные кавычки в String с интерполяцией в scala
Не удается избежать всех кавычек в моей функции
(базовое использование этого → если я найду строку, ничего не делаю, если ее не добавить строку в начале и конце)
фрагмент кода:
def putTheDoubleQuotes(value: Any): Any = {
value match {
case s: String => s //do something ...
case _ => s"\"$value\"" //not working
}
}
Единственное, что сработало, было:
case _ = > s "" \" $value\ " ""
Есть ли лучший синтаксис для этого?
он выглядит ужасно, и IDE (IntelliJ) отмечает его красным цветом (но позволяет запускать его, что действительно меня злит!!!!!)
Ответы
Ответ 1
Это ошибка в Scala:
escape не работает со строковой интерполяцией
но, возможно, вы можете использовать:
scala> import org.apache.commons.lang.StringEscapeUtils.escapeJava
import org.apache.commons.lang.StringEscapeUtils.escapeJava
scala> escapeJava("this is a string\nover two lines")
res1: java.lang.String = this is a string\nover two lines
Ответ 2
Вам не нужно скрывать кавычки в трехколейной строке, поэтому s""""$value"""""
будет работать. По общему признанию, он тоже выглядит не очень хорошо.
Ответ 3
Другое решение (также упомянутое в Scala tracker) заключается в использовании
case _ => s"${'"'}$value${'"'}"
Все еще некрасиво, но иногда может быть предпочтительным по сравнению с тройными кавычками.
Кажется, что escape-последовательность $"
была предложена как часть SIP-24 для 2.12 - я не уверен, что текущий статус принятия этого предложения, но если принято, можно написать:
case _ => s"$"$value$""
Ответ 4
Для вашего случая использования они упрощают достижение хорошего синтаксиса.
scala> implicit class `string quoter`(val sc: StringContext) {
| def q(args: Any*): String = "\"" + sc.s(args: _*) + "\""
| }
defined class string$u0020quoter
scala> q"hello,${" "*8}world"
res0: String = "hello, world"
scala> "hello, world"
res1: String = hello, world // REPL doesn't add the quotes, sanity check
scala> " hello, world "
res2: String = " hello, world " // unless the string is untrimmed
Белка неявно скрывается в объекте пакета.
Вы можете назвать интерполятор чем-то, кроме q
, конечно.
На прошлой неделе кто-то спросил в ML о возможности использования идентификаторов backquoted. Прямо сейчас вы можете сделать res3, но не res4:
scala> val `"` = "\""
": String = "
scala> s"${`"`}"
res3: String = "
scala> s"hello, so-called $`"`world$`"`"
res4: String = hello, so-called "world"
Еще одна идея, которая только что пришла мне в голову, заключалась в том, что f-интерполятор уже выполняет некоторую работу по массированию вашей строки. Например, он должен обрабатывать "% n" разумно. В то же время он может обрабатывать дополнительный выход "% q", который он не будет передавать в базовый форматтер.
Это будет выглядеть так:
scala> f"%qhello, world%q"
<console>:9: error: conversions must follow a splice; use %% for literal %, %n for newline
Это стоит вопрос об улучшении.
Обновление: только что заметили, что восьмеричные значения не устарели при интерполяции:
scala> s"\42hello, world\42"
res12: String = "hello, world"
Ответ 5
Это фиксировало проблему для меня, я проверил это, и это то, что я использовал.
raw"""
Inside this block you can put "as many" quotes as you "want" and even "${5 + 7}" interpolate inside the quotes
"""
http://docs.scala-lang.org/overviews/core/string-interpolation.html#the-raw-interpolator
Ответ 6
Как уже упоминалось, это известная ошибка в Scala. Обходным путем является использование \042
.
Ответ 7
Как насчет
s"This is ${"\"" + variable + "\""}" inserted in string with quotes
Ответ 8
Это сильно используется в моем случае, поэтому я создал эту версию:
object StringUtil{
implicit class StringImprovements(s: String) {
def quoted = "\""+s+"\""
}
}
val myStatement = s"INSERT INTO ${tableName.quoted} ..."
Ответ 9
Принимая предложение @Pascalius еще на несколько шагов. класс StringImprovements расширяет и наследует AnyVal.
object StringUtil{
implicit class StringImprovements(val s: String) extends AnyVal {
def dqt = "\""+s+"\"" // double quote
def sqt = s"'$s'" // single quote
}
}
Scala использует только класс StringImprovements для создания промежуточного объекта, для которого неявным образом следует вызов двух методов расширения dqt и sqt. Тем не менее, мы можем исключить создание этого объекта и повысить производительность, сделав наследование класса у AnyVal. Для Scala задает тип значения специально для таких случаев, когда компилятор заменит объект, просто сделав вызов метода напрямую.
Вот простой пример использования указанного неявного класса в промежутке, где мы используем именованные переменные (string и boolean) и функцию в строке интерполяции.
import StringUtil._
abstract class Animal {
...
override def toString(): String = s"Animal:${getFullName().dqt}, CanFly:$canFly, Sound:${getSound.dqt}"
}
Ответ 10
Простой способ: -
val str="abc"
println(s"$str") //without double quotes
println(s"""\"$str\"""") // with double quotes