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

Как вставить двойные кавычки в 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) отмечает его красным цветом (но позволяет запускать его, что действительно меня злит!!!!!)

4b9b3361

Ответ 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"

Ответ 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