Задачи на строки
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 string
2) Что выведет программа? Как исправить?
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