Зачем заменять «заглавную» на проверку того, является ли она строчной перед вызовом «заглавной»?

#string #kotlin #title-case

Вопрос:

При использовании Kotlin 1.5 Android Studio предупреждает, что String.capitalize это устаревшее.

Предлагаемая замена заключается в:

 myString.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() })
 

Почему проверка isLowerCase необходима?

Почему я не могу просто сделать это:

 myString.replaceFirstChar { it.titlecase(Locale.getDefault()) })
 

Ответ №1:

Цитата из билета:

Кроме того, у пользователей могут быть разные ожидания относительно поведения fun String.capitalize(): String , и эти ожидания не всегда совпадают с тем, что мы реализовали (см. Продолжение обсуждения). В названии функции указывается первый символ получателя String , только если это строчная буква. Например, результат "DŽ".capitalize() есть "DŽ" , в то время "dž".capitalize() как есть "Dž" . Учитывая различные ожидания, мы хотели бы ввести функцию replaceFirstChar, чтобы пользователи могли писать именно то, что они хотят.

Замены многословны, но сохраняют поведение как можно ближе. Полученный код может быть еще более упрощен, если требуется более простое поведение, например, для String.replaceFirstChar { it.uppercaseChar() } .


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

Я полагаю, это потому, что они хотели воспроизвести оригинальное поведение. В настоящее время capitalize реализуется как:

 public fun String.capitalize(locale: Locale): String {
    if (isNotEmpty()) {
        val firstChar = this[0]
        if (firstChar.isLowerCase()) {
            return buildString {
                val titleChar = firstChar.titlecaseChar()
                if (titleChar != firstChar.uppercaseChar()) {
                    append(titleChar)
                } else {
                    append(this@capitalize.substring(0, 1).uppercase(locale))
                }
                append(this@capitalize.substring(1))
            }
        }
    }
    return this
}
 

Кроме того, согласно примечанию:

Заглавный регистр символа обычно совпадает с его верхним регистром, за несколькими исключениями.

Есть несколько угловых случаев:

 fun check(x: String) {
    println(x.capitalize())
    println(x.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() })
    println(x.replaceFirstChar { it.titlecase() })
}

fun main() {
    check("dz")
    check("DZ")
}
 

Выход (игровая площадка):

 Dz
Dz
Dz
DZ
DZ
Dz
 

Комментарии:

1. Обратите внимание, что, хотя это исправление пытается воспроизвести то же поведение, capitalize что и . Они не совсем одинаковые. Для лигатуры capitalized возвращается FF , в то время как исправление возвращается Ff . Не говорю, что вы все равно должны использовать capitalize ! Я думаю, что последний результат имеет больше смысла.

2. Отличная мысль! Кстати, я также нашел билет на это изменение — youtrack.jetbrains.com/issue/KT-43023