Я хотел бы декапитализировать первую букву данной строки. Я просмотрел пакеты чехлов и струн, самое близкое, что я нашел, было cases.Title
cases.Title(language.Und, cases.NoLower).String("MyString")
Который может принимать второй аргумент cases.someThing
, но с этим я не могу найти способ добиться снижения только первого символа.
PS. Использование версии 1.20
Я не понимаю вашего вопроса. Я пытаюсь взять строку «HelloJim» и преобразовать ее в «helloJim».
Да, взять первую букву ("руну") и сделать ее строчной. Для этого нет универсальной функции, потому что это не то, что вы обычно делаете.
например myString = strings.ToLower(myString[:1]) + myString[1:]
@Gavin: это не удастся для любых многобайтовых символов Юникода, поэтому я упомянул «руну».
@JimB Ах, ты прав. Возможно, что-то вроде runes := []rune(myString); myString = strings.ToLower(string(runes[0])) + string(runes[1:])
было бы лучше: go.dev/play/p/_JMeOMuusgq
Или просто используйте unicode.ToLower()
вместо многократного преобразования в строку.
Что-то вроде этого?
https://goplay.tools/snippet/c7b_OZ19oMC
func firstLetterToLower(s string) string {
if len(s) == 0 {
return s
}
r := []rune(s)
r[0] = unicode.ToLower(r[0])
return string(r)
}
Go был разработан и реализован для поддержки эффективных программ. Простой тест Go ("Hello World"
и "hello World"
) показывает 222.2 ns/op
и 2 allocs/op
для вашей функции и 50.28 ns/op
и 1 allocs/op
для моей функции. Для строки, в которой первый символ уже находится в нижнем регистре ("hello World"
), тест показывает 110.9 ns/op
и 1 allocs/op
для вашей функции и 6.00 ns/op
и 0
allocs/op для моей функции.
В Go напишите простую и эффективную функцию.
package main
import (
"fmt"
"unicode"
"unicode/utf8"
)
func firstToLower(s string) string {
r, size := utf8.DecodeRuneInString(s)
if r == utf8.RuneError && size <= 1 {
return s
}
lc := unicode.ToLower(r)
if r == lc {
return s
}
return string(lc) + s[size:]
}
func main() {
fmt.Println(firstToLower("Hello World"))
fmt.Println(firstToLower("hello World"))
}
https://go.dev/play/p/Vtx75XKWJsD
hello World
hello World
Альтернативное решение без использования библиотеки unicode
для латинских символов ASCII. Поскольку значение байта нижнего регистра этих символов на 32 больше по сравнению с верхним регистром, это должно работать.
package main
import (
"fmt"
)
func main() {
fmt.Println(toLowerFirstC("Hello World"))
}
func toLowerFirstC(s string) string {
if len(s) != 0 && (s[0] <= 90 && s[0] >= 65) {
return string(s[0] + 32) + string(s[1:])
}
return s
}
Выход:
hello World
Go создан для удобочитаемости. Не используйте «волшебные» числа. Go создан для производительности. Самые ранние тесты должны исключать большинство случаев. Если первый тест s[0] >= 'A'
, то все прописные и строчные буквы включены во второй тест s[0] <= 'Z'
. Однако, если первый тест — s[0] <= 'Z'
, то во второй тест включаются только прописные буквы s[0] >= 'A'. Смотрите go.dev/play/p/PyRl_1-f72V.
Поскольку я использовал оператор &&, проверка значения будет застревать между «Z» и «A». Ни в первый s[0] <= 'Z'
, ни в первый s[0] >= 'A'
не будут включены все символы.
Для логических операторов Go правый операнд оценивается условно (закорочено): && conditional AND p && q is "if p then q else false"
. Рассмотрим все 52 латинские буквы ASCII в верхнем и нижнем регистре. Для вашей медленной версии (b >= 'A' && b <= 'Z')
: ifA 52 ifZ 52 AandZ 26
, то есть b >= 'A'
выполняется 52 раза, b <= 'Z'
выполняется 52 раза, а логическая операция верна 26 раз. Для моей быстрой версии (b <= 'Z' && b >= 'A')
: ifZ 52 ifA 26 ZandA 26
, то есть b >= 'A' выполняется только 26 раз. Смотрите go.dev/play/p/bxU18uB7iqJ.
спасибо за руководство. я понял, что вы имеете в виду.
Не существует общего формата для «строчной первой буквы строки». Почему бы просто не взять первую букву и не изменить ее на строчную?