刚才看到了Scala中的一个插入器函数s,觉得真好玩,写出来与大家分享。
s是StringContext类的一个简写形式,来看看StringContext的源码
case class StringContext(parts: String*) { import StringContext._ /** Checks that the length of the given argument `args` is one less than the number * of `parts` supplied to the enclosing `StringContext`. * @param `args` The arguments to be checked. * @throws IllegalArgumentException if this is not the case. */ def checkLengths(args: Seq[Any]): Unit = if (parts.length != args.length + 1) throw new IllegalArgumentException("wrong number of arguments ("+ args.length +") for interpolated string with "+ parts.length +" parts") /** 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) /** 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 } /** 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 ???}
看到源码后,一切都明白了,例子
//s函数的应用val name = "James"s"Hello,$name" //Hello,Jamess"1+1=${1+1}" //1+1=2