8

Scala 2.10.0-RC1 を使用して、たとえば次のように、Windows ファイル パス内で文字列補間を使用しようとしました。

val path = s"""c:\foo\bar\$fileName.csv""" 

そして例外を得た

java.lang.StringIndexOutOfBoundsException: String index out of range: 11

複数行の文字列リテラル ( """) がなくても問題なく機能します val path = s"""c:\foo\bar\$fileName.csv""" val path = s"c:\foo\bar\${fileName}.csv " //> パス: 文字列 = c:\foo\bar\myFile.csv

問題を再現するためのさらなるテスト:

object wcScala10 {

  util.Properties.versionString   //> res0: String = version 2.10.0-RC1
  val name = "James"              //> name  : String = James
  val test1 = s"Hello $name"      //> test1  : String = Hello James
  val test2 = s"""Hello $name"""  //> test2  : String = Hello James
  val test3 = """Hello \$name"""  //> test3  : String = Hello \$name
  val test4 = s"""Hello \$name""" //> java.lang.StringIndexOutOfBoundsException: 
                                  //>   String index out of range: 7
}

この例外はバグによるものですか? または、文字列補間を行うときに $ 記号の前にバックスラッシュを使用することは許可されていませんか?

スタックトレースの詳細は次のとおりです。

java.lang.StringIndexOutOfBoundsException: String index out of range: 7
    at java.lang.String.charAt(String.java:686)
    at scala.collection.immutable.StringOps$.apply$extension(StringOps.scala :39)
    at scala.StringContext$.treatEscapes(StringContext.scala:202)
    at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:90)
    at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:90)
    at scala.StringContext.standardInterpolator(StringContext.scala:120)
    at scala.StringContext.s(StringContext.scala:90)
    at wcScala10$$anonfun$main$1.apply$mcV$sp(wcScala10.scala:9)
    at org.scalaide.worksheet.runtime.library.WorksheetSupport$$anonfun$$exe
 cute$1.apply$mcV$sp(WorksheetSupport.scala:76)
    at org.scalaide.worksheet.runtime.library.WorksheetSupport$.redirected(W
 orksheetSupport.scala:65)
    at org.scalaide.worksheet.runtime.library.WorksheetSupport$.$execute(Wor
 ksheetSupport.scala:75)
    at wcScala10$.main(wcScal
 Output exceeds cutoff limit.

アップデート:

Scala 2.10.1-RC1 で修正済みとしてマークされました

https://issues.scala-lang.org/browse/SI-6631

ちなみに、修正後でも、補間を行ってエスケープを回避する正しい方法は、次を使用することですraw

val path = raw"c:\foo\bar\$fileName.csv"

例えば

val fileName = "myFileName"               //> fileName  : String = myFileName
val path = raw"c:\foo\bar\$fileName.csv"  //> path  : String = c:\foo\bar\myFileName.csv
4

1 に答える 1

8

文字列補間表記は、文字列が生の文字列であるかどうかの制御を引き継ぎます。トリプルクォートで得られるのは、シングルクォートを引用する機能だけです。補間が必要ない場合は、raw"Hi $name"代わりに使用してください。(raw2.10.0でもバグがあることを除いて、2.10.1 AFAIKで修正が行われています。)

とは言うものの、これは文字列のフォーマットが正しくない状況に対処するための非常に友好的な方法ではありません。エスケープコードを完了できないというものではなく、範囲外の例外を返すという理由だけで、バグとして分類します。

注:これらの休憩も:

s"Hi \$name"
s"""Hi \"""
于 2012-11-08T20:43:11.427 に答える