👾Мой канал в Telegram: t.me/ntuzov Пишу там новости, анонсы своих активностей и просто интересные мысли Также я получаю в нём от вас оперативный фидбэк по роликам - что нравится, что не нравится, какой ролик делать следующим и т.п. ❤ Если у вас есть желание поддержать развитие канала: Секретный телеграм-канал: - В рублях: t.me/+1UPXV_DGnG1mODJi - В евро: t.me/+hedI8LevYTc5MDM6 boosty.to/nikolay.tuzov www.patreon.com/tuzov
пожалуйста сделай такой же разбор теории на все темы в Go Твой канал сразу наберет обороты, у тебя получается объяснять очень хорошо, а вот сразу архиваторы и боты писать это уже потом будут смотреть! Теория по основным темам всем по 10 минут на ролик зайдет идеально! сразу подпишусь на патреон если последуешь совету))
@@blackfoxvideo5971 это уже в процессе. Завтра как раз будет видео с подробным разбором внутреннего устройства Map. Я тоже решил, что серии практических уроков заходят людям хуже, и собираюсь сосредоточиться на одиночных.
Важное уточнение! Слайс может перезаписывать базовый массив, а может и нет. Если сразу добавить append новые элементы, больше, чем капасити, сразу создастся новый участок памяти и перезапишет все элементы. Так базовый массив не изменится. Если добавлять элементы по одному, то сначала перезапишется базовый массив, когда его вместимость закончится, тогда создастся новый массив. В зависимости от количества добавляемых элементов, базовый массив меняется , либо нет.
for_, num := range nums { tips = append(tips, num * 2)
} return tips } подскажите где ошибка ? при варианте 1 , компилятор ругается: # command-line-arguments ./HelloWorld.go:12:16: syntax error: unexpected range, expecting expression ./HelloWorld.go:16:3: syntax error: non-declaration statement outside function body подскажите Николай я переправирил раз 20 строчка в строчку.. даже на листе выписал 2 вариант вами описаный работает с индексам в цикле и с размером результирующего слайса вместо емкости ( как в 1 варианте) а вот 1 вариант не проходит выкидывая ошибки выше . !? Спасибо
Если ты также будешь продолжать все доходчиво разжевывать в Go- тематике, чего сейчас мало на ру сегменте, то однозначно будешь одним из лучших) Спасибо!
Идеальный гайд по слайсам, must have для любого новичка. Скинул ссылку на урок всем знакомым, пусть подтягивают слайсы и закрывают пробелы Автору огромное спасибо за труд!
Golang | Slice в деталях, простым языком Спасибо за видео, как раз сейчас изучаю Golang. Практики вообще "бомба" (делал []Type{}). Жду новых видео. Спасибо.
Спасибо большое за все эти уроки по ГО. Я очень люблю Low-Level понимание процессов и на каждом видео получил необычайное удовольствие. Этот материал как раз тот, которого мне не хватало чтобы начать работать с ГО. (я не новичок и мне просто не хватало хорошего материала которые разъясняет все эти нюансы) Спасибо-спасибо-спасибо
Спасибо Книгу читаю по Go, думал, что ничего нового не узнаю тут, чисто закрепить хотел, а правильное использование append и про маленький слайс и большой слайс - прям круто, спасибо
Николай, спасибо за подробный обзор! Грамотная речь и четкое понимание материала делает просмотр видео приятным, интересным и понятным с первого раза. Уверен, что это видео поможет многим начинающим гоферам закрыть пробелы, а некоторым и найти новую работу))) Всем удачи на собеседованиях!
посмотрев твои видео, джун будет знать больше чем лид) Работаю 2 года на Го, но как работает под капотом узнал все у тебя. Спасибо тебе большое за видео!
спасибо за полезные видео, тот случай когда хочется сделать замедление скорости видео, так как количество полезной информации не удается воспринять за один присест)
Спасибо. Я решил немного отдохнуть, но сейчас у меня в процессе новый ролик - про хэш-таблицы. Он будет в новом формате, на который требуется очень много времени. Ждите =)
Однозначно лайк!жаль что не все темы по базовому уровню. Знаю что у разработчиков как всегда нет времени,но если вы вдруг запишите курс,Вселенная вас отблагодарит
Спасибо - отличный материал с кучей подводных сущностей и деталей 👍 Которые были снова мастерски объяснены. Уже небольшая ломка начинается без твоих роликов - пиши исчо! ❤
Стараюсь сейчас изучить каждый аспект, который могут спросить на собеседовании на junior go разработчика. Это видео думаю было идеальным для того чтобы освоить слайсы :))
Отличный материал, странно что мало комментариев. Николай, поделитесь о создании презентации в ваших видео, какими средствами создаете динамические картинки в ваших уроках, очень интересная подача.
У меня на канале есть серия уроков про написание Телеграм-бота, там я, в частности, разбираю и правильную организацию проекта (файлы, пакеты и т.п.), подробно это комментирую. То, что ты ищешь как раз.
Офигенное видео. Все очень доходчиво. Один момент я бы прояснил чуть подробнее. О том, что если нам гарантированно нужен новый слайс, мы должны делать его через copy(), а не через присвоение. Этот момент сильно важен для тех, кто переходит с других языков, в которых присвоение будет именно созданием полной копией со всеми значениями. И, кстати, возможно вы знаете, почему copy() сделана именно так? Сходу представляется вариант newSlice := copy(slice), который будет возвращать структуру нового созданного слайса. Такая конструкция позволяет сэкономить одну строку кода на объявлении нового слайса и не следить за правильностью инициализации нового слайса (длиной). Конечно, есть костыли в виде append, которые позволяют делать копию в одну строку, но они совсем не очевидны.
Хороший вопрос. Так сделано для большей гибкости. К примеру, поищи вызовы функци copy в стандартной библиотеке Go. Далеко не всегда параметры dst слайса будут совпадать с исходным. Например, новый слайс может быть больше исходного (с запасом на какие-то другие элементы). Также ты можешь скопировать два слайса в один новый. И даже больше - ты можешь скопировать конкретный кусочек одного слайса в конкретное место другого: copy(dst[n:m], src[a:b])
@@nikolay_tuzov Угу, спасибо. А был ли где-то рассказ про "бест практис"? Как гуру относятся к оберткам над такими функциями как copy() для реализации именно таких частных случаев? Чтобы в одну строку вызывать. Возможно, есть какие-то стандартные библиотеки, в которых это уже реализовано?
@@ЕвгенийУгожаев-ь7и я думаю, в подобных обертках смысла мало. Они разве что сэкономят тебе строчку кода, но только больше запутают коллег. Во всяком случае, я таких обёрток в рабочих проектах не встречал. Кстати, беседы удобней вести в чате, а не в тредах комментов на ютубе =) Если тебе интересно обсуждать подобные вещи, заглядывай в наш чатик: t.me/+WyjmnP6la_QyYjAy
Спасибо за видео! Единственный минус - мне как новичку довольно сложно пока-что понять что-либо после 15ой минуты. Но так вообще все довольно понятно, благодарю!
Повторюсь, это замечательный урок. Планируется ли что-то подобное про строки? Так как в go, при работе с ними, есть много своих интересных особенностей. )
26:00 Хотя я не пишу на Go пока что, но могу сказать, то что ты предлагаешь в 26:00, все равно файл будет загружаться в память. Для этого и есть стримы (streams) что позволяют читать файл через потоки
Ого да ты что, какой ты умный. Суть была не в том, что файл в память загружается. Там мог быть и не файл, а что угодно, что возвращает большой массив байтов. Суть в том, что в первой реализации мы возвращаем маленький слайс, который при этом держит ссылку на большой массив байтов, что плохо. И во второй реализации мы избавляемся от этой проблемы.
Заодно попробовал написать Append для добавления нескольких элементов, если кому интересно, как это может выглядеть: func Append(slice []int, el ...int) []int { var res []int resLen := len(slice) + len(el) if resLen
По факту это работа с указателями, поймут те кто знает С или ассемблер, но вот интерпретация компилятором Го не совсем понятна. И еще, если объяснять срезы через концепцию указателей, то будет гораздо понятней. Основное отличие массива от указателя, массив определяется ссылкой на область памяти и резервированием области памяти равной объему массива, т.е некий объем памяти постоянно зарезервирован под конкретные данные(жесткая типизация), а указатель это ссылка на объем данных в памяти без резервирования памяти(условно, т.к память ценный ограниченный ресурс) и с произвольной интерпретацией этих данных, для простоты понимания ссылка на буфер и интерпретация данных буфера в зависимости типа полученного сообщения.
У меня получилось так. Не сказать, что ваириант более красивый, с copy вариант как по мне более понятный при чтении func FindDigits(filename string) []byte { b, _ := os.ReadFile(filename) b = digitRegexp.Find(b) return append([]byte{}, b...) }
на 17:00 вы объявили переменную _ (нижний прочерк) и сразу выполнили присвоение функции append но при этом перед названием этой переменной _ нет ни слова var или чего то еще. Это что то свойственное go? как это называется?
Здесь этот знак означает присваивание значения "пустой переменной". На самом деле, конкретно здесь его использовать не обязательно, без него код будет работать точно так же. Здесь он полезен только с точки зрения кодстайла - таким образом я демонстрирую явным образом, что функция append что-то возвращает, и я это "что-то" сознательно игнорирую. Если такой знак не использовать, то визуально невозможно отличить подобный случай от того, когда функция ничего не возвращает. Но в некоторых случаях без этого символа вообще не обойтись. Например, когда функция возвращает несколько значений, а нам нужно лишь одно из них. Мы не можем присвоить ненужное значение обычной переменной, т.к. Го обяжет нас эту переменную как-то использовать. Аналогично в циклах - если мы делаем итерации по какому-то списку или мапе, и нам не нужен ключ и значение, то мы присваиваем его "пустой переменной".
@@nikolay_tuzov вы так ясно объясняете. вообще удивительно, что такое качество образовательного материала, обратной связи и скорости доступно бесплатно. надеюсь для вас в этом есть хоть доля выгоды, может не в виде денег, ну хотя бы умственное или эмоциональное. спасибо еще раз
@@jimshtepa5423 вы всё правильно пишете - это "выгодно" в умственном и эмоциональном плане. Я делаю это на чистом энтузиазме, и очень радуюсь, что людям нравится результат =)
27:03 Более красивый вариант с append - он подразумевался таким или нет? :) func findDigits(filename string) []byte { b, _ := os.ReadFile(filename) b = digitRegexp.Find(b) return append(make([]byte, 0, len(b)), b...) }
Здравствуйте, спасибо за видео, не могу его просмотреть к сожалению целиком, потому что в моменте возникают вопросы и прошу вашей помощи. на 5:34 вы создаете новый slice с 4 по 7 (не включительно) элемент и у него сразу capacity 9, не совсем понимаю почему так, вы же взяли всего 3 элемента в ваш slice то есть у него и длина должна быть 3 и capacity 3. Или тут нюанс что когда я беру новый slice от какого другого slice то я беру его от индекса элемента что я указал в начале и всегда до конца? Заранее спасибо за ответ!
Зря дальше не смотрите, ведь дальше я как раз это и объясняю. Плюс потом мы на практике будем закреплять. Поэтому всегде лучше сначала досмотреть до конца, а потом задавать вопросы. capacity 9 потому, что базовый массив у нас сохранился прежний, и у него ещё есть "запас" по объёму
Я не знаю Го, но судя по синтаксису у тебя ошибки в коде. В цикле удвоения, ты не с элементами входящего среза работаешь, а с индексом цикла, т.е никакого удвоения входных значений не происходит.
@@nikolay_tuzov почитал про range и for и пустой идентификатор. Синтаксис получается раздолбайский, в отличие от классических языков и проблема в том что формально цикл работает пока истина, а range таких значений не возвращает, т.е по факту компилятор интерпретирует любое значение кроме пустого как истина. Посмотрел несколько сайтов по Го и нигде этот ньюанс не описан, только пример дан, что вот так вот работает.
@@evgenyvolkov7075 и в чем ньюанс? range работает очевидно: выполняется, пока текущий индекс меньше длины коллекции. Т.е. по факту получается, что ты вначале не разобрался и написал чушь про индекс/элемент, потом почитал сайты, ничего не понял и снова написал чушь.
Удивительно, что создатели го сделали слайс на базе массива. Куда эффективнее было бы использовать для этого связный список Это позволило бы быстро работать с динамически выделяемой память, а - что самое главное! - не копировать каждый раз исходный массив при увеличении capacity Боюсь представить, сколько лишней памяти отжирает операция расширения емкости( Оставляя старый массив на неизвестно какое долгое ожидание сборщика мусора
Если бы это был вопрос, то он был бы хорошим. Но я всё равно постарался ответить развёрнуто, в отдельном посте в ТГ-канале: t.me/ntuzov/384 (сори за байт на тг, но там длинные тексты писать и читать сильно проще, чем в комментах ютуба)
@@nikolay_tuzov забавные у вас комментаторы в тг)) ни они, ни вы не учли фразу "на базе (массива/списка)". это не значит, что нужно использовать эти структуры в чистом виде, а лишь говорит о том, как менеджерить эти данные в памяти. лишь один, как видно, опытный программист, подметил, что далеко не обязательно юзать list в чистом виде, можно обмазать это доп структурами, чтобы оптимизировать работу с процом и памятью. вот ответьте сами - в том же ядре linux или в базовой либе языка go каждая структура и алгоритм используются ТОЛЬКО в чистом виде?)) по-моему как раз у вас на канале есть ролик про хэш-мапы, и там объединено несколько подходов, чтобы взять плюсы от каждого подхода хотя, с точки зрения блогерства вы правы, что возвели мои тезисы в абсолют, ведь это принесло вам доп комменты и контент для тг 😁😅
Ну это только для тебя удвивительно. Доступ к n-му элементу массива это О(1), а у связного списка - О(n), а обращение к элементу слайса по индексу это достаточно частая операция. Я молчу про всякие оптимизации, когда при обходе массива все его элементы могут загружаться в кеш процессора, что значительно ускоряет обработку, а со связным списком это невозможно. Ладно иметь две реализации слайса (массив + связный список), но иметь одну реализацию только на связном списке это абсурд.
@@user-mr-m12312 читайте внимательно. я написал "на базе массива"! это не значит, что нужно только одну структуру внутри использовать! те же хэш-мапы под капотом имеют несколько структур для оптимального хранения, беря плюсы от разных подходов) учите матчасть)
Не надо мне самостоятельная практика. Я за информацией пришел и за идеями лучших реализаций, более глубокого понимания. Если мне надо, я напишу без видосиков и домашних заданий. У меня самостоятельная практика каждый день по 8 часов.
Не смог повторить пример func findDigits(filename string) []byte { digitRegexp := regexp.MustCompile("[0-9]+") bytes, err := os.ReadFile(filename) if err != nil { log.Println(err) } return digitRegexp.Find(bytes) } Сделал файл с таким содержанием "12345 dfdf 123454" Запускаю digits := findDigits("test.txt") log.Println(len(digits), cap(digits), string(digits)) // 5 5 12345 Т.е. нет такого что мы будем тянуть за собой весь файл... или есть какой-то способ так сделать?
👾Мой канал в Telegram: t.me/ntuzov
Пишу там новости, анонсы своих активностей и просто интересные мысли
Также я получаю в нём от вас оперативный фидбэк по роликам - что нравится, что не нравится, какой ролик делать следующим и т.п.
❤ Если у вас есть желание поддержать развитие канала:
Секретный телеграм-канал:
- В рублях: t.me/+1UPXV_DGnG1mODJi
- В евро: t.me/+hedI8LevYTc5MDM6
boosty.to/nikolay.tuzov
www.patreon.com/tuzov
пожалуйста сделай такой же разбор теории на все темы в Go Твой канал сразу наберет обороты, у тебя получается объяснять очень хорошо, а вот сразу архиваторы и боты писать это уже потом будут смотреть! Теория по основным темам всем по 10 минут на ролик зайдет идеально! сразу подпишусь на патреон если последуешь совету))
@@blackfoxvideo5971 это уже в процессе. Завтра как раз будет видео с подробным разбором внутреннего устройства Map.
Я тоже решил, что серии практических уроков заходят людям хуже, и собираюсь сосредоточиться на одиночных.
Важное уточнение! Слайс может перезаписывать базовый массив, а может и нет.
Если сразу добавить append новые элементы, больше, чем капасити, сразу создастся новый участок памяти и перезапишет все элементы. Так базовый массив не изменится.
Если добавлять элементы по одному, то сначала перезапишется базовый массив, когда его вместимость закончится, тогда создастся новый массив.
В зависимости от количества добавляемых элементов, базовый массив меняется , либо нет.
package main
import "fmt"
func main() {
list := []int{4,5,7,8,3}
fmt.Println(double(list))
}
func double(nums []int) []int {
tips := make([]int, 0, len(nums))
for_, num := range nums {
tips = append(tips, num * 2)
}
return tips
}
подскажите где ошибка ? при варианте 1 , компилятор ругается: # command-line-arguments
./HelloWorld.go:12:16: syntax error: unexpected range, expecting expression
./HelloWorld.go:16:3: syntax error: non-declaration statement outside function body
подскажите Николай я переправирил раз 20 строчка в строчку.. даже на листе выписал 2 вариант вами описаный работает с индексам в цикле и с размером результирующего слайса вместо емкости ( как в 1 варианте)
а вот 1 вариант не проходит выкидывая ошибки выше . !?
Спасибо
Кринжеёбище💀💀💀
Если ты также будешь продолжать все доходчиво разжевывать в Go- тематике, чего сейчас мало на ру сегменте, то однозначно будешь одним из лучших) Спасибо!
@@artemxeon1654значит ты тройник, даже я понял, а я двойник
Из всех, кого слушал, Николай лучший
ванганул))
Наконец то нормальный лектор с внятной полноценной подачей.
Жаль, не все темы есть, но заходит оч круто.
Николай, спасибо большое за такую годную БЕСПЛАТНУЮ инфу. Круто, когда начинаешь понимать не только работу, но и внутрянку механизма!
Видео просто шикарно, очень доходчиво и приятная подача материала. Ну и голос тоже очень приятный.
Крутой материал, все по делу без воды, спасибо)
Ждем такой же только про map-ы)
Спасибо) На мой взгляд, мапы в Го чуть менее интересны, но можно совместить это с общим рассказом про хэш-таблицы. Подумаю на эту тему.
@@nikolay_tuzov хорошая тема)
Идеальный гайд по слайсам, must have для любого новичка. Скинул ссылку на урок всем знакомым, пусть подтягивают слайсы и закрывают пробелы
Автору огромное спасибо за труд!
Golang | Slice в деталях, простым языком
Спасибо за видео, как раз сейчас изучаю Golang.
Практики вообще "бомба" (делал []Type{}).
Жду новых видео. Спасибо.
Спасибо большое за твою работу! Очень ждем продолжения. В частности практические примеры разработки с деталями - rest api в частности.
Благодарю за добрые слова =)
Спасибо большое за все эти уроки по ГО. Я очень люблю Low-Level понимание процессов и на каждом видео получил необычайное удовольствие.
Этот материал как раз тот, которого мне не хватало чтобы начать работать с ГО. (я не новичок и мне просто не хватало хорошего материала которые разъясняет все эти нюансы)
Спасибо-спасибо-спасибо
Очень круто. Люблю Го, очень здорово что кто-то внятно рассказывает о его внутреннем устройстве. Самому трудно во всем разобраться.
Спасибо
Книгу читаю по Go, думал, что ничего нового не узнаю тут, чисто закрепить хотел, а правильное использование append и про маленький слайс и большой слайс - прям круто, спасибо
Николай, спасибо за подробный обзор! Грамотная речь и четкое понимание материала делает просмотр видео приятным, интересным и понятным с первого раза. Уверен, что это видео поможет многим начинающим гоферам закрыть пробелы, а некоторым и найти новую работу))) Всем удачи на собеседованиях!
Спасибо! Очень приятно видеть такой фидбэк =)
до чего же подробно и понятно, спасибо большое!
Только недавно начал осваивать go, материал действительно годный, удачи тебе
очень крутое объяснение и бестпрактисы.
Да если так же будут объяснены интерфейсы, чистая архитектура, мапы будет лучшее не только на ру сегменте.
Спасибо. Про интерфейсы и мапы точно будет, на счёт "чистой архиктуры" пока думаю.
Николай Тузов видео сделано доходчево понятное для понимания спасибо тебе)
Николай, пожалуйста не бросайте нас 😢, жду новых видео или подкастов )
Не брошу =)
Сейчас занимаюсь большим роликом по планировщику Go, поэтому новых видео нет. За обновлениями можете следить тут: t.me/ntuzov
посмотрев твои видео, джун будет знать больше чем лид) Работаю 2 года на Го, но как работает под капотом узнал все у тебя. Спасибо тебе большое за видео!
22:26 по мне так самая неочевидная особенность ф-и append. полезно, спасибо
спасибо за полезные видео, тот случай когда хочется сделать замедление скорости видео, так как количество полезной информации не удается воспринять за один присест)
Спасибо за прекрасный материал и отличное объяснение! :)
Очень интересно и понятно. Спасибо!
Мне очень зашло.Бро продолжай только не пропадай!!!Господа это like!!!
Спасибо. Я решил немного отдохнуть, но сейчас у меня в процессе новый ролик - про хэш-таблицы. Он будет в новом формате, на который требуется очень много времени. Ждите =)
@@nikolay_tuzov ЖДЁМ!!!
Шикарное объяснение! Большое спасибо!
Спасибо
Классный урок!
Однозначно лайк!жаль что не все темы по базовому уровню.
Знаю что у разработчиков как всегда нет времени,но если вы вдруг запишите курс,Вселенная вас отблагодарит
Спасибо - отличный материал с кучей подводных сущностей и деталей 👍
Которые были снова мастерски объяснены. Уже небольшая ломка начинается без твоих роликов - пиши исчо! ❤
Стараюсь сейчас изучить каждый аспект, который могут спросить на собеседовании на junior go разработчика. Это видео думаю было идеальным для того чтобы освоить слайсы :))
как всё прошло ?
Огненный видос, спасибо за твою работу)
Очень интересно. Спасибо что делаешь такой контент. Именно то что я искал
Отличный материал, странно что мало комментариев. Николай, поделитесь о создании презентации в ваших видео, какими средствами создаете динамические картинки в ваших уроках, очень интересная подача.
Отличный разбор! Автору большое спасибо)
Очень классное видео, спасибо!
Спасибо, отличный урок
Хотелось бы в будущем еще увидеть тему про пакеты. Как вообще правильно организовывать файлы и по какому принципу.
У меня на канале есть серия уроков про написание Телеграм-бота, там я, в частности, разбираю и правильную организацию проекта (файлы, пакеты и т.п.), подробно это комментирую. То, что ты ищешь как раз.
Спасибо, Николай!
Супер,спасибо. Творческих успехов и здоровья 🙏🏻❤️
Благодарю за видео. Продолжайте в том же духе, это очень полезно.
Очень хотелось бы от тебя видео по планировщикам и по переключению контекста.
Это как раз в работе, скоро будет
Офигенное видео. Все очень доходчиво. Один момент я бы прояснил чуть подробнее. О том, что если нам гарантированно нужен новый слайс, мы должны делать его через copy(), а не через присвоение. Этот момент сильно важен для тех, кто переходит с других языков, в которых присвоение будет именно созданием полной копией со всеми значениями.
И, кстати, возможно вы знаете, почему copy() сделана именно так? Сходу представляется вариант newSlice := copy(slice), который будет возвращать структуру нового созданного слайса. Такая конструкция позволяет сэкономить одну строку кода на объявлении нового слайса и не следить за правильностью инициализации нового слайса (длиной). Конечно, есть костыли в виде append, которые позволяют делать копию в одну строку, но они совсем не очевидны.
Хороший вопрос. Так сделано для большей гибкости.
К примеру, поищи вызовы функци copy в стандартной библиотеке Go. Далеко не всегда параметры dst слайса будут совпадать с исходным. Например, новый слайс может быть больше исходного (с запасом на какие-то другие элементы).
Также ты можешь скопировать два слайса в один новый.
И даже больше - ты можешь скопировать конкретный кусочек одного слайса в конкретное место другого: copy(dst[n:m], src[a:b])
@@nikolay_tuzov То есть, по сути, copy() предназначена не для копирования слайса, а для копирования значений из одного слайса в другой?
@@ЕвгенийУгожаев-ь7и в общем случае да, именно так. Полное копирование - это частный случай.
@@nikolay_tuzov Угу, спасибо. А был ли где-то рассказ про "бест практис"? Как гуру относятся к оберткам над такими функциями как copy() для реализации именно таких частных случаев? Чтобы в одну строку вызывать. Возможно, есть какие-то стандартные библиотеки, в которых это уже реализовано?
@@ЕвгенийУгожаев-ь7и я думаю, в подобных обертках смысла мало. Они разве что сэкономят тебе строчку кода, но только больше запутают коллег. Во всяком случае, я таких обёрток в рабочих проектах не встречал.
Кстати, беседы удобней вести в чате, а не в тредах комментов на ютубе =)
Если тебе интересно обсуждать подобные вещи, заглядывай в наш чатик: t.me/+WyjmnP6la_QyYjAy
Это супер🤩 Про работу с со строками было бы здорово увидеть похожий разбор
Спасибо за видео! Единственный минус - мне как новичку довольно сложно пока-что понять что-либо после 15ой минуты. Но так вообще все довольно понятно, благодарю!
Привет. Что сейчас скажешь? Как успехи в изучении? Я только начал, еще 2 недель нет. Информации очень много, но усваивается пока не все..
@@stanleypomogiti8633 привет)
Поизучал пару месяцев и пересел на Python + sql + C
Через год планирую вернуться в Go
Видео очень полезное, спасибо.
Респект автору! Удачи каналу.
Спасибо за видео!
Хотелось бы что то похожее увидеть про горутины и каналы
Это обязательно будет
Отличное видео. Еще бы хороший ролик по чанам и поинтерам.
Спасибо =) По этим темам тоже обязательно будут видео
Спасибо. Очень понятно
5:30 срез начиная с середины массива
7:05 append
8:07 увеличение емкости
Полезно. Спасибо!!
Очень познавательно. Спасибо
Спасибо! Очень полезно
Спасибо за годный урок
было полезно, спасибо!
Мой тысячный лайк )
здраствуйте, есть ои у вас на канале уроки по учению Golang? что то я не нашел
Класс!
годно, а есть видео про Full slice expressions?
func double(nums []int) (res []int) {
res = nums[:]
for i := range len(res) {
res[i] *= 2
}
return
}
Повторюсь, это замечательный урок. Планируется ли что-то подобное про строки? Так как в go, при работе с ними, есть много своих интересных особенностей. )
Вполне возможно, запишу на будущее, спасибо =)
Очень интересно, но скорость очень быстрая , для новичка трудно не потерять мысль повествования
Parabéns pelo vídeo
26:00 Хотя я не пишу на Go пока что, но могу сказать, то что ты предлагаешь в 26:00, все равно файл будет загружаться в память. Для этого и есть стримы (streams) что позволяют читать файл через потоки
Ого да ты что, какой ты умный.
Суть была не в том, что файл в память загружается. Там мог быть и не файл, а что угодно, что возвращает большой массив байтов.
Суть в том, что в первой реализации мы возвращаем маленький слайс, который при этом держит ссылку на большой массив байтов, что плохо. И во второй реализации мы избавляемся от этой проблемы.
Примите во внимание что начиная с go 1.18 функция append выделяет память по другому алгоритму
Заодно попробовал написать Append для добавления нескольких элементов, если кому интересно, как это может выглядеть:
func Append(slice []int, el ...int) []int {
var res []int
resLen := len(slice) + len(el)
if resLen
Спасибо лайк
По факту это работа с указателями, поймут те кто знает С или ассемблер, но вот интерпретация компилятором Го не совсем понятна. И еще, если объяснять срезы через концепцию указателей, то будет гораздо понятней. Основное отличие массива от указателя, массив определяется ссылкой на область памяти и резервированием области памяти равной объему массива, т.е некий объем памяти постоянно зарезервирован под конкретные данные(жесткая типизация), а указатель это ссылка на объем данных в памяти без резервирования памяти(условно, т.к память ценный ограниченный ресурс) и с произвольной интерпретацией этих данных, для простоты понимания ссылка на буфер и интерпретация данных буфера в зависимости типа полученного сообщения.
У меня получилось так. Не сказать, что ваириант более красивый, с copy вариант как по мне более понятный при чтении
func FindDigits(filename string) []byte {
b, _ := os.ReadFile(filename)
b = digitRegexp.Find(b)
return append([]byte{}, b...)
}
Можешь сказать, что у тебя шрифт, толстота в ide?
Для записи я использую "режим презентации" в GoLand, настройки шрифтов стандартные:
View -> Appearance -> Enter Presentation Mode
Спасибо!
Зачем размер только в make не пони, мне лично капасити интересно только )
на 17:00 вы объявили переменную _ (нижний прочерк) и сразу выполнили присвоение функции append но при этом перед названием этой переменной _ нет ни слова var или чего то еще. Это что то свойственное go? как это называется?
Здесь этот знак означает присваивание значения "пустой переменной".
На самом деле, конкретно здесь его использовать не обязательно, без него код будет работать точно так же. Здесь он полезен только с точки зрения кодстайла - таким образом я демонстрирую явным образом, что функция append что-то возвращает, и я это "что-то" сознательно игнорирую. Если такой знак не использовать, то визуально невозможно отличить подобный случай от того, когда функция ничего не возвращает.
Но в некоторых случаях без этого символа вообще не обойтись. Например, когда функция возвращает несколько значений, а нам нужно лишь одно из них. Мы не можем присвоить ненужное значение обычной переменной, т.к. Го обяжет нас эту переменную как-то использовать. Аналогично в циклах - если мы делаем итерации по какому-то списку или мапе, и нам не нужен ключ и значение, то мы присваиваем его "пустой переменной".
@@nikolay_tuzov вы так ясно объясняете. вообще удивительно, что такое качество образовательного материала, обратной связи и скорости доступно бесплатно. надеюсь для вас в этом есть хоть доля выгоды, может не в виде денег, ну хотя бы умственное или эмоциональное. спасибо еще раз
@@jimshtepa5423 вы всё правильно пишете - это "выгодно" в умственном и эмоциональном плане. Я делаю это на чистом энтузиазме, и очень радуюсь, что людям нравится результат =)
Как происходит обнуление данных во вновь выделенной памяти?
Переписываетя каждый байт?
годно
27:03 Более красивый вариант с append - он подразумевался таким или нет? :)
func findDigits(filename string) []byte {
b, _ := os.ReadFile(filename)
b = digitRegexp.Find(b)
return append(make([]byte, 0, len(b)), b...)
}
Мне кажется что вариант с копированием слайса будет лучше и читабельней :d
спасибо! кстати, тУзов или тузОв?)
Здравствуйте, спасибо за видео, не могу его просмотреть к сожалению целиком, потому что в моменте возникают вопросы и прошу вашей помощи.
на 5:34 вы создаете новый slice с 4 по 7 (не включительно) элемент и у него сразу capacity 9, не совсем понимаю почему так, вы же взяли всего 3 элемента в ваш slice то есть у него и длина должна быть 3 и capacity 3.
Или тут нюанс что когда я беру новый slice от какого другого slice то я беру его от индекса элемента что я указал в начале и всегда до конца?
Заранее спасибо за ответ!
Зря дальше не смотрите, ведь дальше я как раз это и объясняю. Плюс потом мы на практике будем закреплять. Поэтому всегде лучше сначала досмотреть до конца, а потом задавать вопросы.
capacity 9 потому, что базовый массив у нас сохранился прежний, и у него ещё есть "запас" по объёму
Ребят, какая формула увеличения ёмкости слайса ?
fire
8:21 Пропал элемент "t", который мы аппендили ранее)
ну да, ляпы случаются)
6:06 Почему slice2 = array[6:9], а не slice2 = myArray[6:9] ?
Это опечатка
Оговорка? 13:34 - не длина, а capacity
30 минут смотрел два дня (((
Выглядит так как будто в го не хватает более сложной сущности которая при апенде не теряет ссылки.
Видео конечно полезное, но язык (go) юмористический, смотрю просто чтобы поржать
Зачем его назвали slice не понятно. Вообще не соответствует функционалу
Я не знаю Го, но судя по синтаксису у тебя ошибки в коде. В цикле удвоения, ты не с элементами входящего среза работаешь, а с индексом цикла, т.е никакого удвоения входных значений не происходит.
Если ты про 12:29, то там всё верно. Стоит познакомиться с синтаксисом Go =)
Если в другом месте, то покажи тайминг
@@nikolay_tuzov почитал про range и for и пустой идентификатор. Синтаксис получается раздолбайский, в отличие от классических языков и проблема в том что формально цикл работает пока истина, а range таких значений не возвращает, т.е по факту компилятор интерпретирует любое значение кроме пустого как истина. Посмотрел несколько сайтов по Го и нигде этот ньюанс не описан, только пример дан, что вот так вот работает.
@@evgenyvolkov7075 и в чем ньюанс? range работает очевидно: выполняется, пока текущий индекс меньше длины коллекции. Т.е. по факту получается, что ты вначале не разобрался и написал чушь про индекс/элемент, потом почитал сайты, ничего не понял и снова написал чушь.
Че то какой то стремный язык, почему нельзя было сделать как в других нормальных языках.
Удивительно, что создатели го сделали слайс на базе массива. Куда эффективнее было бы использовать для этого связный список
Это позволило бы быстро работать с динамически выделяемой память, а - что самое главное! - не копировать каждый раз исходный массив при увеличении capacity
Боюсь представить, сколько лишней памяти отжирает операция расширения емкости(
Оставляя старый массив на неизвестно какое долгое ожидание сборщика мусора
Если бы это был вопрос, то он был бы хорошим. Но я всё равно постарался ответить развёрнуто, в отдельном посте в ТГ-канале: t.me/ntuzov/384
(сори за байт на тг, но там длинные тексты писать и читать сильно проще, чем в комментах ютуба)
@@nikolay_tuzov класс! спасибо, пойду читать)
@@nikolay_tuzov забавные у вас комментаторы в тг)) ни они, ни вы не учли фразу "на базе (массива/списка)". это не значит, что нужно использовать эти структуры в чистом виде, а лишь говорит о том, как менеджерить эти данные в памяти. лишь один, как видно, опытный программист, подметил, что далеко не обязательно юзать list в чистом виде, можно обмазать это доп структурами, чтобы оптимизировать работу с процом и памятью. вот ответьте сами - в том же ядре linux или в базовой либе языка go каждая структура и алгоритм используются ТОЛЬКО в чистом виде?)) по-моему как раз у вас на канале есть ролик про хэш-мапы, и там объединено несколько подходов, чтобы взять плюсы от каждого подхода
хотя, с точки зрения блогерства вы правы, что возвели мои тезисы в абсолют, ведь это принесло вам доп комменты и контент для тг
😁😅
Ну это только для тебя удвивительно. Доступ к n-му элементу массива это О(1), а у связного списка - О(n), а обращение к элементу слайса по индексу это достаточно частая операция. Я молчу про всякие оптимизации, когда при обходе массива все его элементы могут загружаться в кеш процессора, что значительно ускоряет обработку, а со связным списком это невозможно. Ладно иметь две реализации слайса (массив + связный список), но иметь одну реализацию только на связном списке это абсурд.
@@user-mr-m12312 читайте внимательно. я написал "на базе массива"! это не значит, что нужно только одну структуру внутри использовать! те же хэш-мапы под капотом имеют несколько структур для оптимального хранения, беря плюсы от разных подходов) учите матчасть)
мда, урок супер, слайсы после других яп - редкостное убожество
Не надо мне самостоятельная практика. Я за информацией пришел и за идеями лучших реализаций, более глубокого понимания. Если мне надо, я напишу без видосиков и домашних заданий. У меня самостоятельная практика каждый день по 8 часов.
@World of Fear чел, я учу своих коллег и чему-то учусь сам. Можешь не жалеть их, у них всё хорошо. О себе позаботься.
я нихуя не понимаю
Не смог повторить пример
func findDigits(filename string) []byte {
digitRegexp := regexp.MustCompile("[0-9]+")
bytes, err := os.ReadFile(filename)
if err != nil {
log.Println(err)
}
return digitRegexp.Find(bytes)
}
Сделал файл с таким содержанием "12345 dfdf 123454"
Запускаю
digits := findDigits("test.txt")
log.Println(len(digits), cap(digits), string(digits)) // 5 5 12345
Т.е. нет такого что мы будем тянуть за собой весь файл... или есть какой-то способ так сделать?
походу за 2 года был фикс
спасибо, очень подробно