Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Я хочу получать рассылки с лучшими постами за неделю
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
Создавая аккаунт, я соглашаюсь с правилами Пикабу и даю согласие на обработку персональных данных.
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр Битва Героев: RPG - увлекательная игра в жанре РПГ.

Битва Героев: RPG

Приключения, Фэнтези

Играть

Топ прошлой недели

  • AlexKud AlexKud 38 постов
  • Animalrescueed Animalrescueed 36 постов
  • Oskanov Oskanov 7 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая кнопку «Подписаться на рассылку», я соглашаюсь с Правилами Пикабу и даю согласие на обработку персональных данных.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
0 просмотренных постов скрыто
0
bahamutjuice
bahamutjuice
15 дней назад

Наблюдения за выходящими аниме⁠⁠

открыл для себя - Zatsu Tabi: That's Journey
вышло этими весной-летом, с апреля по июнь.

https://shikimori.one/animes/55514-zatsu-tabi-that-s-journey
рисовка такая себе и полное отсутствие сюжета - сплошные путешествия девочек по достопримечательностям Японии. и да, там показывают больше Японию, чем девочек.
такое впечатление, что на финансирование этого аниме скидывались министерство культуры Японии и министерство туризма, если там такие есть.

но к моему расслабленному наблюдению за слайсами и за культурой очень даже подошло.

Аниме Япония Слайсы Текст
3
636
ErdigiDocSS13
ErdigiDocSS13
7 месяцев назад
Юмор для всех и каждого

Зима⁠⁠

Зима
Помидоры Зима Юмор Картинка с текстом Слайсы Срез Парейдолия
22
FreshAngry007
1 год назад

Слайсы и Go⁠⁠

Слайсы в Go — это удобный, динамический интерфейс к массивам. Они обеспечивают большую гибкость, по сравнению с традиционными массивами. В отличие от массивов, размер слайса не является частью его типа, что позволяет слайсам быть гораздо более динамичными.

Слайс состоит из трех компонентов:

  • Указатель на начальный элемент массива, к которому применяется слайс.

  • Длина слайса (len), указывающая на количество элементов в слайсе.

  • Емкость слайса (cap), которая указывает на максимальное количество элементов, начиная с текущего указателя, до конца базового массива.

Как слайсы работают

Когда вы создаете слайс, Go автоматически выделяет под него массив в памяти. Слайс предоставляет ссылку на начало этого массива и позволяет работать с его частью. Изменение элементов слайса напрямую влияет на соответствующие элементы массива, так как слайс является просто "окном" в массив.

Динамическое изменение размера

Одной из ключевых особенностей слайсов является их способность динамически изменять размер. Функция append позволяет добавлять элементы в слайс. Если при добавлении элемента емкость слайса недостаточна для размещения нового элемента, Go автоматически выделяет новый, больший массив и копирует в него элементы из старого. В результате, слайс начинает ссылаться на новый массив.

Создание и инициализация

Слайсы можно создать несколькими способами:

  • Используя оператор make, который позволяет указать тип, начальную длину и (необязательно) емкость слайса. Например, make([]int, 5, 10).

  • Через литерал слайса, например, []int{1, 2, 3}.

  • Оператором [:], [low:high], [low:high:max] для создания слайса из массива или другого слайса.

Подводные камни

Необходимо быть осторожным при работе со слайсами, особенно при передаче их в функции или возвращении из них, так как они могут ссылаться на одни и те же данные в памяти. Также, стоит помнить, что увеличение емкости слайса происходит путем выделения нового массива и копирования в него данных, что может быть дорогостоящей операцией с точки зрения производительности при работе с большими объемами данных.

Пара примеров с подводными камнями при работе со слайсами в Go:

1. Непреднамеренное изменение базового массива

При передаче слайса в функцию или возвращении его из функции, вы фактически передаете ссылку на базовый массив. Это значит, что изменения, сделанные в слайсе внутри функции, отразятся на исходном слайсе.

package main

import "fmt"

func modifySlice(s []int) {

s[0] = 999 // Изменяет первый элемент базового массива

}

func main() {

originalSlice := []int{1, 2, 3}

modifySlice(originalSlice)

// Вывод: [999 2 3]

fmt.Println(originalSlice)

}

В этом примере, изменяя слайс внутри функции modifySlice, мы также изменяем исходный слайс originalSlice, потому что оба они ссылаются на один и тот же базовый массив.

1.1. Решение

Нужно модифицировать функцию так, чтобы она возвращала новый слайс вместо изменения переданного ей слайса. Это дает вызывающему коду контроль над тем, должен ли исходный слайс быть изменен.

package main

import "fmt"

func CopyAndModifySlice(s []int) []int {

// Создаем новый слайс и копируем в него данные из s

newSlice := make([]int, len(s))

copy(newSlice, s)

// Изменяем новый слайс

newSlice[0] = 999

return newSlice

}

func main() {

originalSlice := []int{1, 2, 3}

modifynewSlice := CopyAndModifySlice(originalSlice)

// Вывод: [1 2 3]

fmt.Println(originalSlice)

// Вывод: [999 2 3]

fmt.Println(modifynewSlice )

}

2. Утечка памяти из-за неправильного срезания слайсов

Слайс хранит ссылки на базовый массив, и если вы создаете новый слайс на основе части большого массива, но при этом больше не используете исходный большой массив, он всё равно не будет собран сборщиком мусора до тех пор, пока существует хотя бы один слайс, ссылающийся на его часть.

package main

import "fmt"

func getSmallSlice() []int {

// Большой массив

bigSlice := make([]int, 1000000)

// Маленький слайс, ссылается на начало большого массива

smallSlice := bigSlice[:3]

return smallSlice

}

func main() {

smallSlice := getSmallSlice()

fmt.Println(cap(smallSlice)) // Вывод: 1000000

// В этот момент вся память, занимаемая bigSlice, все еще занята,

// несмотря на то что мы работаем только с маленьким сегментом.

}

В этом примере, bigSlice больше недоступен после выполнения getSmallSlice, но память, которую он занимает, остается занятой из-за smallSlice, который ссылается на часть bigSlice. Это может привести к неэффективному использованию памяти, особенно если подобный код выполняется многократно.

2.1. Решение

package main

import "fmt"

func getSmallSlice() []int {

// Большой массив

bigSlice := make([]int, 1000000)

// Создаем новый слайс того же размера, что и нужный маленький слайс

smallSlice := make([]int, 3)

// Копируем данные из большого массива в маленький слайс

copy(smallSlice, bigSlice[:3])

return smallSlice

}

func main() {

smallSlice := getSmallSlice()

fmt.Println(cap(smallSlice)) // Вывод: 3

// Теперь большой массив может быть собран сборщиком мусора,

// так как на него нет ссылок в виде слайса.

}

3. Увеличение емкости (capacity) слайса неявно

При добавлении элементов к слайсу его емкость может быть неявно увеличена, что приводит к созданию нового базового массива и копированию элементов из старого массива в новый. Этот процесс может быть неочевидным и привести к снижению производительности при неправильном использовании.

package main

import "fmt"

func main() {

// Слайс с начальной емкостью 1

s := make([]int, 0, 1)

prevCap := cap(s)

// Потенциально много раз увеличиваем емкость

for i := 0; i < 1024; i++ {

if cap(s) != prevCap {

fmt.Printf("Емкость изменилась с %d на %d\n", prevCap, cap(s))

prevCap = cap(s)

}

s = append(s, i)

}

}

// Емкость изменилась с 1 на 2

// Емкость изменилась с 2 на 4

// Емкость изменилась с 4 на 8

// Емкость изменилась с 8 на 16

// Емкость изменилась с 16 на 32

// Емкость изменилась с 32 на 64

// Емкость изменилась с 64 на 128

// Емкость изменилась с 128 на 256

// Емкость изменилась с 256 на 512

// Емкость изменилась с 512 на 848

// Емкость изменилась с 848 на 1280

В этом примере слайс s начинается с емкости 1 и увеличивается многократно по мере добавления элементов, что может привести к множественным аллокациям памяти и копированиям.

3.1. Решение

package main

import "fmt"

func main() {

// Заранее выделяем слайс с нужной емкостью

// Емкость сразу выделена под 1024 элемента

s := make([]int, 0, 1024)

// Добавляем элементы, не вызывая дополнительных аллокаций

for i := 0; i < 1024; i++ {

s = append(s, i)

}

// Вывод: 1024 1024

fmt.Println(len(s), cap(s))

}

// емкость не менялась не разу

4. Потенциальная потеря данных при неосторожном использовании append

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

package main

import "fmt"

func main() {

s1 := make([]int, 0, 5)

// s2 указывает на новый слайс

s2 := append(s1, 1)

// s3 тоже указывает на новый слайс, но уже другой

s3 := append(s1, 2)

// [] [1] [2] - s1 остается без изменений

fmt.Println(s1, s2, s3)

}

Это поведение может привести к неожиданным результатам, если предполагается, что append изменит исходный слайс.

4.1. Решение

Чтобы избежать потенциальной потери данных при использовании append, особенно когда вы работаете с исходным слайсом, который может не иметь достаточной емкости для добавления новых элементов, важно убедиться, что вы корректно обрабатываете возвращаемое значение от append. append возвращает новый слайс, который может указывать на тот же или новый базовый массив в зависимости от емкости исходного слайса.

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

package main

import "fmt"

func main() {

s1 := make([]int, 0, 5)

// Присваиваем результат append обратно s1

s1 = append(s1, 1)

// s2 теперь будет содержать [1 2]

s2 := append(s1, 2)

// Вывод: [1] [1 2] - s1 изменен корректно

fmt.Println(s1, s2)

}

Поиграться с примерами можно тут https://go.dev/play

Показать полностью
[моё] Программирование Golang IT Длиннопост Текст Слайсы
0
1
bahamutjuice
bahamutjuice
1 год назад
Аниме

Манга "Ёцуба"⁠⁠

давно-давно в РФ часть её перевели и издали. я встречал и купил тогда до восьмого тома, включительно - сейчас эти восемь томов стоят у меня на полке. палма-пресс - если кто помнит.
но на рутрекере можно найти переведенную фанатами и поклонниками мангу "Ёцуба" до 16 тома включительно. и скачать. и читать потом. ещё плюс десять томов.
формат файлов там своеобразный: cbz - зип-архив картинок, упорядоченных по каталогам.
но
1. обычным менеджером архивов всё равно всё можно достать покартинково и смотреть и вставлять куда хочешь и я так уже делал.
2. читалка e-book вроде и сама умеет этот формат распаковывать и показывать.
а calibre у меня выдала ошибку при открытии этих архивов, хотя вроде бы должна распознавать.. может у вас распознает.

Манга Картинки Слайсы Текст
2
Vasiliipepel
4 года назад
Сообщество рыболовов

Приготовление котлет из щуки⁠⁠

[моё] Кухня Рыбные котлеты Рыбалка Слайсы Видео
4
Bromteh
Bromteh
6 лет назад

Фелы со слайсами⁠⁠

Слайсы Fail Видео YouTube
4
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии