Scala编译器是否可以处理UTF-8编码的源文件?

Scala编译器是否可以处理UTF-8编码的源文件?,scala,Scala,我有一个非常简单的Scala代码 var str = "≤" for( ch <- str ) { printf("%d, %x", ch.toInt, ch.toInt) ; println } println str = "\u2264" ; for( ch <- str ) { printf("%d, %x", ch.toInt, ch.toInt) ; println } 显然,第一个字符串在运行时是3个字符长,而不是源文件中的1个字符长 源文件存储在UTF-8

我有一个非常简单的Scala代码

 var str = "≤"
 for( ch <- str ) { printf("%d, %x", ch.toInt, ch.toInt) ; println  }
 println
 str = "\u2264" ;
 for( ch <- str ) { printf("%d, %x", ch.toInt, ch.toInt) ; println }
显然,第一个字符串在运行时是3个字符长,而不是源文件中的1个字符长

源文件存储在UTF-8中。十六进制转储显示其编码正确,第一个字符串是22 E2 89 A4 22。我正在使用Eclipse和用于Eclipse的Scala插件

  • scala编译器是否接受UTF-8编码的输入文件?
  • 如果是,为什么我的程序会产生意想不到的结果?

是,Scala完全支持UTF-8

我无法复制你的结果。MacOSX、Java7、Scala2.10.4

检查系统的文件编码:

scala> System.getProperty("file.encoding")
res0: String = UTF-8
将此行添加到.bashrc。这可能会解决某些*nix环境中的问题

export JAVA_OPTS='-Dfile.encoding=UTF-8'

有时IDE设置为错误的文件编码。您也可以检查此项。

回答我自己的问题:

scala编译器是否可以处理UTF-8编码的文件

是的,但前提是它知道它们是UTF-8编码的。在没有任何其他证据的情况下,它使用Java的
file.encoding
属性。(感谢@AndreasNeumann给出这部分答案。)

为什么我的程序没有按我预期的那样运行

因为我的
file.encoding
属性设置为
MacRoman
。尽管我告诉eclipse该文件是UTF-8,但这个信息并没有传递给Scala编译器。因此,编译器根据
MacRoman
编码将3字节序列E289 A4解释为一个三字符序列:一个较低的单引号(看起来很像逗号)、一个“a”扬抑符和一个段符号。这个3个字符序列的unicode是U+201A U+00E2 U+00A7,这解释了我的程序的输出

你如何解决这个问题

在上,使用选项
-编码UTF-8
。在eclipse中,您可以使用Scala插件的首选项(选项)来添加此选项。(感谢@Jesper给出这部分答案。)您还可以在
scalac
命令行上或通过
JAVA\u OPTS
环境变量使用
-D
选项来设置
file.encoding
属性。(详见@AndreasNeumann的答案。)

如果使用,至少可以做三件事

  • 一种是在Eclipse的全局首选项(或选项)中的General>>Workspace下为所有工作空间设置默认编码,如Iulian Dragos的回答所示
  • 在项目属性中(右键单击Package Explorer中的项目,选择
    属性
    ),在
    资源
    首选项下,选择UTF-8作为
    文本文件编码
  • 最后,您可以在首选项(或选项)中的编译器>>Scala下的
    附加命令行参数下添加
    -encoding UTF-8
    。可以将其设置为全局首选项(或选项)或项目特定的特性设置。

Scala插件尊重Eclipse的编码设置。可以在“首选项”中设置工作区默认值。如果这没有渗透到源代码中,请检查在项目或源文件夹级别是否存在覆盖编码

例如,以下是源文件夹的属性页:


“Scala编译器是否可以处理UTF-8编码的源文件?”答案是肯定的。奇怪的是,如果我告诉eclipse将编码更改为MacRoman,它会将字符串显示为三个字符。如果随后将其编辑回1并保存,则字符串将保存为一个字符:B2。编译,运行。它起作用了!因此,如果文件是用UTF-8编码的,eclipse似乎无法通知scala编译器这是真的,scala编译器正在进行处理,就好像文件是用其他编码一样。这解释了除特定的3个字符以外的所有内容。为什么201a e2 a7而不是e2 89 a4?我真的不在乎。我确实想知道如何告诉Scala采用何种编码。使用
scalac
在命令行上编译代码时,请使用
-encoding
选项指定源文件的编码。例如:
scalac-编码UTF-8 MyProgram.scala
谢谢@Jesper。这提供了一个很好的解决办法。另外,当我这样做时,包含非SCII字符的MacRoman编码文件会出现编译时错误。所以我不会不小心使用了错误的编码,除非所有字符都在0000和00FF之间——在这种情况下,这并不重要。谢谢。我正在使用eclipse,那里的解释器显示“MacRoman”。我想我在想,如果我告诉Eclipse一个文件是UTF-8格式的,它会以某种方式将其传递给编译器。嗯……认为自己拥有JAVA_OPTS的脚本太多了。我从来都不喜欢这种方法……在JVM上的多克隆项目中工作时,它有很多好处。否则很难保证互操作性。您应该在工作区首选项中设置默认编码。IDE无论如何都会添加-编码,所以现在您要听命于命令行解析,以及-编码需要什么precedence@IulianDragos谢谢我想我已经试过了,但我想不是在全球范围内。是否有特定于项目的方法来实现这一点?无论如何,我会编辑我的答案。好的。找到了特定于项目的解决方案。将再次编辑。
export JAVA_OPTS='-Dfile.encoding=UTF-8'