Scala против Java toUpperCase / toLowerCase - PullRequest
2 голосов
/ 02 марта 2020

Scala заимствования Java String такие методы, как toUpperCase / toLowerCase .

Однако это не так очень непротиворечиво:

  • Scala на палочке JVM близко к семантике Java, таким образом:
    • toUpperCase() чувствительно к локали и придерживается локали по умолчанию (давая вам печально → İ проблема в Turki sh locale)
    • , чтобы избежать этого и сохранить нечувствительный к локали (en_US / C-like) процесс, вам нужно специально выполнить toUpperCase(Locale.ROOT)
  • Scala. JS не реализует концепцию Locale , таким образом:
    • toUpperCase() работает без учета локали
    • * Метод 1029 * фактически недоступен в ScalaJS

Как реализовать преобразование регистра без учета локали, которое будет работать в Scala на обеих JVM / JS?

Я могу думать о нескольких способах, все они как уродливые:

Метод 1: Моя собственная реализация

Реализация моей собственной toUpperCase для спецификаций 26 символов ASCII на английском языке Engli sh.

Метод 1.1: Моя собственная реализация с использованием Scala символов

В основном то же самое, но, по крайней мере, повторное использование Scala toUpper для преобразования отдельных символов.

Метод 2: Интерфейс

Внедрите что-то вроде

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"

в общий код, а затем в JS есть:

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

object MainJs {
  Main.caseChanger = CaseChangerJs
}

... и в JVM:

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

object MainJvm {
  Main.caseChanger = CaseChangerJvm
}

Метод 3: принести внешние scala - java -locales

Существует отдельная сторонняя библиотека scala - java -locales , который указан как ScalaJS -совместимый, и может использоваться для увеличения ScalaJS.

Похож на однако, излишнее излишнее количество, поскольку мне буквально нужны не зависящие от локали преобразования регистра, но не все для всех возможных локалей.

Есть лучшие идеи?

1 Ответ

8 голосов
/ 02 марта 2020

Стандартный подход близок к вашему методу 2, но намного проще. В общем коде вы просто вызываете

Platform.toUpperLocaleInsensitive(string)

, который имеет различные реализации в 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
}

См. Описание аналогичного случая в Практика Scala. js.

Это работает, потому что совместно используемый код не должен компилироваться сам по себе, только вместе с указанным для платформы c кодом.

...