Scala vs Java toUpperCase/toLowerCase

Gre*_*Cat 2 java locale scala case-sensitive scala.js

Scala 借用了 Java String方法,例如toUpperCase / toLowerCase

然而,它这样做的方式并不是很一致:

  • JVM 上的 Scala 贴近 Java 语义,因此:
    • toUpperCase() 对语言环境敏感并坚持默认语言环境(给您带来臭名昭著的 i ? ? 土耳其语言环境问题)
    • 为避免这种情况并保持区域设置不敏感(en_US / C-like)过程,您需要专门执行 toUpperCase(Locale.ROOT)
  • Scala.JS 没有实现Locale的概念,因此:
    • toUpperCase() 以不区分区域设置的方式工作
    • toUpperCase(Locale locale) 方法在 ScalaJS 中实际上不可用

如何在 JVM/JS 上的 Scala 中实现不区分区域设置的大小写转换?

我可以想到几种方法,它们都很丑陋:

方法一:我自己的实现

toUpperCase为英文字母表的 26 个 ASCII 字符实现我自己的。

方法 1.1:我自己使用 Scala 字符实现

基本相同,但至少重用 Scala toUpper来转换单个字符。

方法二:接口

实现类似的东西

trait CaseChangeOps {
  def toUpperCase(s: String): String
}

object Main {
  var caseChanger: CaseChanger
}

// whenever I want to use it, do it like that:
Main.caseChanger.toUpperCase("like this") // => "LIKE THIS"
Run Code Online (Sandbox Code Playgroud)

在共享代码中,然后在 JS 中有:

object CaseChangerJs {
  def toUpperCase(s: String): String = s.toUpperCase
}

object MainJs {
  Main.caseChanger = CaseChangerJs
}
Run Code Online (Sandbox Code Playgroud)

...在JVM中:

object CaseChangerJvm {
  def toUpperCase(s: String): String = s.toUpperCase(Locale.ROOT)
}

object MainJvm {
  Main.caseChanger = CaseChangerJvm
}
Run Code Online (Sandbox Code Playgroud)

方法三:带外部scala-java-locales

有一个独特的 3rd 方库scala-java-locales,它被列为与 ScalaJS 兼容,可用于增强 ScalaJS。

不过,这似乎是一个巨大的矫枉过正,因为我实际上只需要对区域设置不敏感的大小写转换,而不是所有可能的区域设置的全部内容。

有什么更好的想法吗?

Ale*_*nov 9

标准方法与您的方法 2 接近,但要简单得多。在共享代码中,您只需调用

Platform.toUpperLocaleInsensitive(string)
Run Code Online (Sandbox Code Playgroud)

在 JVM 和 JS 上有不同的实现:

// JVM
object Platform {
  def toUpperLocaleInsensitive(s: String) = s.toUpperCase(Locale.ROOT)

  // other methods with different implementations
}

// JS
object Platform {
  def toUpperLocaleInsensitive(s: String) = s.toUpperCase()

  // other methods with different implementations
}
Run Code Online (Sandbox Code Playgroud)

请参阅Hands-on Scala.js 中类似案例的描述。

这是有效的,因为共享代码不需要自己编译,只需要与特定于平台的代码一起编译。