Задачи на строки
1) Что выведет данная программа и почему?
package main
import "fmt"
func main() {
s0 := "some string"
s1 := []byte(s0)
s2 := s1[5:]
s2[3] = 'o'
fmt.Println(string(s2))
fmt.Println(string(s1))
fmt.Println(string(s0))
}Давайте разберем, что происходит в данной программе на GoLang шаг за шагом:
s0 := "some string"- создается строкаs0со значением "some string".s1 := []byte(s0)- строкаs0преобразуется в слайс байтовs1. Теперьs1содержит байты, соответствующие каждому символу строки "some string".s2 := s1[5:]- создается слайсs2, который является срезомs1, начиная с 6-го элемента (индексация начинается с 0). Таким образом,s2будет содержать байты, начиная с символа 's' в слове "string".s2[3] = 'o'- четвертый элемент (индекс 3) слайсаs2изменяется на байт, соответствующий символу 'o'. Посколькуs2ссылается на те же данные, что иs1, изменениеs2также изменяетs1. В исходной строке "string" буква 'i' (четвертый символ) заменяется на 'o', получается "strong".
Теперь рассмотрим вывод каждой из строк:
fmt.Println(string(s2))- выводит преобразованныйs2, т.е. "strong".fmt.Println(string(s1))- выводит преобразованныйs1, т.е. "some strong", так как изменения вs2затронули иs1.fmt.Println(string(s0))- выводит исходную строкуs0, которая не изменилась и остается "some string", так как строки в Go иммутабельны и изменения в байтовом слайсе не влияют на исходную строку.
Итак, вывод программы будет следующим:
strong
some strong
some string2) Что выведет программа? Как исправить?
package main
func main() {
s := "test"
println(s[0])
s[0]="R"
println(s)
}Давайте разберем, что произойдет при выполнении этой программы и как ее можно исправить.
Разбор кода
Создание строки
s:s := "test"Здесь создается строка
sсо значением"test".Вывод первого символа строки:
println(s[0])s[0]возвращает первый байт строкиs, который соответствует символу't'. В Go строки являются неизменяемыми последовательностями байтов, поэтомуs[0]вернет байт, соответствующий символу't', что равно116в ASCII.Попытка изменения первого символа строки:
s[0] = 'R'Здесь программа пытается изменить первый символ строки
sна'R'. Однако строки в Go неизменяемы, и попытка изменить их напрямую приведет к ошибке компиляции:cannot assign to s[0]
Исправление программы
Чтобы изменить строку в Go, нужно создать новую строку с необходимыми изменениями. Один из способов сделать это — преобразовать строку в срез байтов, изменить нужный байт, а затем преобразовать срез байтов обратно в строку.
Исправленный код
package main
import "fmt"
func main() {
s := "test"
fmt.Println(s[0]) // Выводит 116, что соответствует 't' в ASCII
// Преобразуем строку в срез байтов
b := []byte(s)
b[0] = 'R'
// Преобразуем срез байтов обратно в строку
s = string(b)
fmt.Println(s) // Выводит "Rest"
}Вывод исправленной программы
Исправленная программа выведет:
116
RestОбъяснение исправленного кода
Преобразование строки в срез байтов:
b := []byte(s)Это позволяет изменять отдельные байты строки.
Изменение первого байта:
b[0] = 'R'Здесь первый байт изменяется на
'R'.Преобразование среза байтов обратно в строку:
s = string(b)Это создает новую строку с измененным содержимым.
Таким образом, исправленный код корректно изменяет первый символ строки и выводит ожидаемый результат. Однако этот код будет работать некоррекно сo строками, содержащими символы, представленные несколькими байтами (например, кириллица или другие символы Unicode), может привести к некорректным результатам. В таких случаях лучше использовать срезы рун (rune), так как руны представляют собой символы Unicode и могут корректно обрабатывать многобайтовые символы.
Исправленный код с использованием рун
package main
import "fmt"
func main() {
s := "тест"
// Преобразуем строку в срез рун
r := []rune(s)
fmt.Println(string(r[0])) // Выводит первый символ строки, что соответствует 'т'
r[0] = 'Р'
// Преобразуем срез рун обратно в строку
s = string(r)
fmt.Println(s) // Выводит "Рест"
}Объяснение исправленного кода
Преобразование строки в срез рун:
r := []rune(s)Это позволяет работать с символами Unicode, включая многобайтовые символы.
Изменение первого символа:
r[0] = 'Р'Здесь первый символ изменяется на
'Р'.Преобразование среза рун обратно в строку:
s = string(r)Это создает новую строку с измененным содержимым.
Вывод исправленной программы
Исправленная программа выведет:
т
РестЗаключение
Использование срезов рун вместо срезов байтов позволяет корректно работать с многобайтовыми символами Unicode, такими как кириллица. Это обеспечивает правильное изменение строк, содержащих такие символы, и предотвращает возможные ошибки, связанные с некорректной обработкой многобайтовых символов.
Last updated