#18.1 golang rune string Работа с символами строки, Руны: посимвольное чтение, Юникод, Uft-8, конкатенация, range()
Primary tabs
Forums:
После того как мы уже поговорили про строки и срезы можно остановить на примере работы со строками как срезом символов.
Тип rune (Руны)
Если наша строка состоит не только из ASCII, где достаточно 1 байта на символ, а и из других символов (например, наша любимая кириллица), то для работы с отдельными символами нам потребуются руны, тип который используется в golang для работы с мультибайтным символами.
Тип для для рун определен так:
type rune = int32
-- т.е. как раз 4 байта для хранения символов юникода.
Обращение к отдельным символам
Для обращения к отдельным символам мы можем преобразовать строку к срезу рун:
package main
import "fmt"
func main() {
s := "Привет!"
runes := []rune(s) // тип для рун опр
fmt.Println("Количество байт:", len(s)) // 13
fmt.Println("Количество символов(рун):", len(runes)) // 7
// чтобы получить конкретный символ как строку string
// требуется явное обратное преоразование через string
fmt.Println("Третья буква:", string(runes[2]))
}
-- где сам golang определят тип для рун как:
type rune = int32
-- т.е. как раз 4 байта для хранения символов юникода.
В примере выше мы посмотрели разобрали общее разбираение юникод-строки на символы и обращение к конкретному символу. Далее посмотрим на конкатенацию символов - как вообще "пересобирать" новые строки из старых.
Перебор символов строки - range()
В golang при использовании цикла for по строке range позволяет сразу перебирать именно руны (а не байты):
func main() {
s := "Привет!"
for i, r := range s {
fmt.Printf("Позиция: %d, Символ: %c, Код: %d\n", i, r, r)
}
}
-- тут используется форматированный вывод, если мы хотим использовать простую распечатку, то нужно будет приводить наши символы к строковому типу явно:
func main() {
s := "Привет!"
for i, r := range s {
fmt.Println("Символ:", string(r), "Код:", i)
}
}
Конкатенация рун - символов из строки
Для конкатенации символов можно использовать несколько способов:
import (
"fmt"
"strings"
)
func main() {
s1 := "привет"
s2 := "мир"
// Преобразуем строки в срезы рун
runes1 := []rune(s1)
runes2 := []rune(s2)
// Берём третий символ из каждой строки (индекс 2)
char1 := runes1[2] // 'и'
char2 := runes2[2] // 'р'
// Далее вариаты конкатенации
// Вариант 1 - литеральное объявление среза
// Создаём срез рун из двух символов
combinedRunes := []rune{char1, char2}
strValue := string(combinedRunes)
fmt.Println("Итог:", strValue)
// Вариант 2- конкатенация через билдер
var builder strings.Builder
builder.WriteRune(runes1[2]) // Добавляем первый символ
builder.WriteRune(runes2[2]) // Добавляем второй символ
// тут есть отдельный способ для получения строки:
strValue = builder.String()
fmt.Println("Итог:", strValue)
// Вариант 3 - прямая конкатенация строк
strValue = string(runes1[2]) + string(runes2[2])
fmt.Println("Итог:", strValue)
}
Пример кода: Обмен, перестановка символов в строке
На тему данного урока хорошо ложится решение популярной алгоритмической задачи про разворот строки:
import "fmt"
func reverseString(s string) string {
// Преобразуем строку в срез рун для корректной работы с Unicode
runes := []rune(s)
n := len(runes)
// Меняем местами символы с начала и конца, двигаясь к центру
for i := 0; i < n/2; i++ {
runes[i], runes[n-1-i] = runes[n-1-i], runes[i]
}
return string(runes)
}
func main() {
fmt.Println(reverseString("Привет!")) // Вывод: "olleh"
fmt.Println(reverseString("Golang")) // Вывод: "oG"
fmt.Println(reverseString("")) // Пустая строка: ""
}
-- тут мы используем цикл и офорляем логику решение в виде функции.
- Log in to post comments
- 81 reads