Scala字符串变量代换

Scala中基础的字符串插值就是在字符串前面加字符s,然后在字符串中放入变量,每个变量都应该用$字符开头,eg.

    val name = "Yrz"
    val age = 4
    val weight = 15.00
    println(s"$name is $age years old, and his weight is $weight")

输出如下:

Yrz is 4 years old, and his weight is 15.0

在字符串的变量中使用表达式

除了把变量放到字符串中外,还可以使用花括号把表达式包起来再放到字符串中。根据官方文档,${}内可以嵌入任何表达式,eg.

println(s"$name is ${age + 1} years old, and his weight is $weight")

输出如下:

Yrz is 5 years old, and his weight is 15.0

也可以在${}中使用==表达式,eg.

println(s"Is $name 4 years old? ${age == 4}")

输出如下:

Is Yrz 4 years old? true

可以通过${}来输出对象中的变量,eg.

case class Student(val name:String, val score: Int)

val yrz:Student = new Student("Yrz", 100)
    println(s"The score of ${yrz.name} is ${yrz.score}")

输出如下:

The score of Yrz is 100

s是一个方法

作为插值的s实际上是一个方法,在StringContext.scala中定义如下:

/** The simple string interpolator.
   *
   *  It inserts its arguments between corresponding parts of the string context.
   *  It also treats standard escape sequences as defined in the Scala specification.
   *  Here's an example of usage:
   *  {{{
   *    val name = "James"
   *    println(s"Hello, $name")  // Hello, James
   *  }}}
   *  In this example, the expression $name is replaced with the `toString` of the
   *  variable `name`.
   *  The `s` interpolator can take the `toString` of any arbitrary expression within
   *  a `${}` block, for example:
   *  {{{
   *    println(s"1 + 1 = ${1 + 1}")
   *  }}}
   *  will print the string `1 + 1 = 2`.
   *
   *  @param `args` The arguments to be inserted into the resulting string.
   *  @throws IllegalArgumentException
   *          if the number of `parts` in the enclosing `StringContext` does not exceed
   *          the number of arguments `arg` by exactly 1.
   *  @throws StringContext.InvalidEscapeException
   *          if a `parts` string contains a backslash (`\`) character
   *          that does not start a valid escape sequence.
   */
  def s(args: Any*): String = standardInterpolator(treatEscapes, args)

字符串插值的好处:

  1. Scala提供了其他更强有力的插值函数;
  2. 可以自定义字符串插值函数;

字符串插值f(printf格式化)

上面的例子中,weight打印的是15.0,如果想打印更多小数位数,或者需要对数字进行格式化操作;这个可以使用“f字符串插值”,一个可以通过printf格式化内部字符串的方法。$weight%.0f保留0位小数, eg.

println(f"$name is ${age + 1} years old, and his weight is $weight%.0f kg")

输出如下:

Yrz is 5 years old, and his weight is 15 kg

$weight%.2f保留两位小数,eg.

println(f"$name is ${age + 1} years old, and his weight is $weight%.2f kg")

输出如下:

Yrz is 5 years old, and his weight is 15.00 kg

如上所述,只需要两步:

  1. 在字符串前加字母f
  2. 在变量之后使用printf的格式化操作符;

fStringContext.scala中的源码如下:

/** The formatted string interpolator.
   *
   *  It inserts its arguments between corresponding parts of the string context.
   *  It also treats standard escape sequences as defined in the Scala specification.
   *  Finally, if an interpolated expression is followed by a `parts` string
   *  that starts with a formatting specifier, the expression is formatted according to that
   *  specifier. All specifiers allowed in Java format strings are handled, and in the same
   *  way they are treated in Java.
   *
   *  For example:
   *  {{{
   *    val height = 1.9d
   *    val name = "James"
   *    println(f"$name%s is $height%2.2f meters tall")  // James is 1.90 meters tall
   *  }}}
   *
   *  @param `args` The arguments to be inserted into the resulting string.
   *  @throws IllegalArgumentException
   *          if the number of `parts` in the enclosing `StringContext` does not exceed
   *          the number of arguments `arg` by exactly 1.
   *  @throws StringContext.InvalidEscapeException
   *          if a `parts` string contains a backslash (`\`) character
   *          that does not start a valid escape sequence.
   *
   *  Note: The `f` method works by assembling a format string from all the `parts` strings and using
   *  `java.lang.String.format` to format all arguments with that format string. The format string is
   *  obtained by concatenating all `parts` strings, and performing two transformations:
   *
   *   1. Let a _formatting position_ be a start of any `parts` string except the first one.
   *      If a formatting position does not refer to a `%` character (which is assumed to
   *      start a format specifier), then the string format specifier `%s` is inserted.
   *
   *   2. Any `%` characters not in formatting positions must begin one of the conversions
   *      `%%` (the literal percent) or `%n` (the platform-specific line separator).
   */
  // The implementation is hardwired to `scala.tools.reflect.MacroImplementations.macro_StringInterpolation_f`
  // Using the mechanism implemented in `scala.tools.reflect.FastTrack`
  def f[A >: Any](args: A*): String = macro ???

raw插入符

sf这两个字符串插入之外,Scala 2.10也包含了其他的插入符,并命名为raw插入符;raw插入符“不会对字符串中的字符进行转义”。对比s插入符和raw插入符,eg:

println(s"foo\nbar")

输出如下:

foo
bar
println(raw"foo\nbar")

输出如下:

foo\nbar

想要避免\n这种操作符变成一个换行符的时候,raw插入符将很有意义;
raw在``中源码如下:

/** The raw string interpolator.
   *
   *  It inserts its arguments between corresponding parts of the string context.
   *  As opposed to the simple string interpolator `s`, this one does not treat
   *  standard escape sequences as defined in the Scala specification.
   *
   *  For example, the raw processed string `raw"a\nb"` is equal to the scala string `"a\\nb"`.
   *
   *  ''Note:'' Even when using the raw interpolator, Scala will preprocess unicode escapes.
   *  For example:
   *  {{{
   *    scala> raw"\u005cu0023"
   *    res0: String = #
   *  }}}
   *
   *  @param `args` The arguments to be inserted into the resulting string.
   *  @throws IllegalArgumentException
   *          if the number of `parts` in the enclosing `StringContext` does not exceed
   *          the number of arguments `arg` by exactly 1.
   */
  def raw(args: Any*): String = standardInterpolator(identity, args)

  def standardInterpolator(process: String => String, args: Seq[Any]): String = {
    checkLengths(args)
    val pi = parts.iterator
    val ai = args.iterator
    val bldr = new JLSBuilder(process(pi.next()))
    while (ai.hasNext) {
      bldr append ai.next
      bldr append process(pi.next())
    }
    bldr.toString
  }

官方文档:http://docs.scala-lang.org/overviews/core/string-interpolation.html#introduction

你可能感兴趣的:(Scala字符串变量代换)