Отличный урок, информация подана с примерами, все понятно, нет лишней воды. 10 из 10. Отдельно хочется отметить приятный голос и адекватное качество звука (многие другие каналы подобным не отличаются, в связи с чем слушать и воспринимать информацию куда тяжелее)
Спасибо за ролик! Это мой второй подход к дженерикам и на этот раз вышел не с кашей в голове 😊 Только вот не понял момент с обобщённым типом в функции unionInterfaceAndType() 17:00 . В чем фишка его использовать, если в функции мы все равно явно должны указать какого конкретного типа мы передаём обобщенный тип, ведь при этом придется писать функцию несколько раз для каждого конкретного типа. Или подразумевается, что пишешь в этой функции switch с type assertion и задаешь поведение для каждого конкретного типа? Тогда опять не понятна эта фишка, ведь по идее делаешь всё как раньше .
Спасибо за урок, выглядят они не привычно ну по сравнению как они выглядят в других языках Rust, C#, Java) будто урезанные дженерики в Golang )))) вот играюсь с дженериками подскажите пожалуйста есть ли вариант написать функцию Map сразу для слайса и хэш мапы лучше чем это УГ: package main import ( "fmt" ) type Collection[T any, K comparable] interface { ~[]T | ~map[K]T } func Map[C Collection[T, K], T any, K comparable](collection C, callback func(item T) T) ([]T, map[K]T) { switch t := any(collection).(type) { case []T: slice := make([]T, 0, len(collection)) for _, el := range t { slice = append(slice, callback(el)) } return slice, nil case map[K]T: hashMap := make(map[K]T, len(collection)) for key, el := range t { hashMap[key] = callback(el) } return nil, hashMap default: return nil, nil } } func main() { list := []uint64{1, 2, 3, 4, 5} person := make(map[string]string) person["leha"] = "blevushkin" person["dima"] = "kekin" person["alex"] = "ssikin" slice, _ := Map[[]uint64, uint64, string](list, func(item uint64) uint64 { return item + 1 }) fmt.Printf("%T %v ", slice, slice) _, hashMap := Map[map[string]string, string, string](person, func(item string) string { return item + "!" }) fmt.Printf("%T %v ", hashMap, hashMap) }
Я думаю надо подождать, посмотреть. Там со временем может и придумают наиболее подходящие юзкейсы, где абстракция будет более полезна, чем скорость. Например для каких то конфигов при запуске приложения.
наверно конечно можно обходится без них, но когда, например, пишешь какую ни будь структуру данных с ними красивее выглядит чем без них) если пишешь библиотечный код без них тоже можно, но с ними будет проще… так-то ясно понятно, что без них можно обойтись в некоторых случаях, например, через полиморфизм
Без компромиссов не обошлось) Видимо тут придется выбирать между быстротой работы vs удобство/cкорость написания кода. Да и в целом создание доп. абстракций всегда накладывает некий оверхед
Как на ютюбе оставлять ссылки?)) Сейчас попробую добавить если автомодерирование пропустит В конце статьи можно увидеть bench. Сам глубоко не вникал, но в интернете их сравнивают с значением interface{}, прирост составляет от 10% до 20% в дженериках, правда аллокаций больше
В целом да, много нового синтаксиса, код становится читать немного сложнее + влияние на производительность. Но идея конечно сама по себе довольно интересная)
Уроки полезные, всё кратко, но ёмко. Одно замечание - сделай, пожалуйста, шрифт крупнее, и/или тему более контрастную. Тяжело читать код
Отличный урок, информация подана с примерами, все понятно, нет лишней воды. 10 из 10. Отдельно хочется отметить приятный голос и адекватное качество звука (многие другие каналы подобным не отличаются, в связи с чем слушать и воспринимать информацию куда тяжелее)
Ну ты красавчик канеш, уважения тебе
Ты офигенен!
спасибо большое )) Топовые уроки )
Благодарю за отличный материал !
Спасибо за информацию, доступно.
Молодец, хорошо разжовываешь.
Давай следующий урок по тестированию
Однозначно лайк, больше обучающих видео по Golang плиз)
лучший бро, 10/10
Красавчик, даже я смог понять)
супер! спасибо!
Спасибо!
спасибо тебе за крутое видео!
подписался и ставил лайк.
Спасибо за ролик! Это мой второй подход к дженерикам и на этот раз вышел не с кашей в голове 😊
Только вот не понял момент с обобщённым типом в функции unionInterfaceAndType() 17:00 . В чем фишка его использовать, если в функции мы все равно явно должны указать какого конкретного типа мы передаём обобщенный тип, ведь при этом придется писать функцию несколько раз для каждого конкретного типа. Или подразумевается, что пишешь в этой функции switch с type assertion и задаешь поведение для каждого конкретного типа? Тогда опять не понятна эта фишка, ведь по идее делаешь всё как раньше .
Спасибо за урок, выглядят они не привычно ну по сравнению как они выглядят в других языках Rust, C#, Java)
будто урезанные дженерики в Golang ))))
вот играюсь с дженериками подскажите пожалуйста есть ли вариант написать функцию Map сразу для слайса и хэш мапы лучше чем это УГ:
package main
import (
"fmt"
)
type Collection[T any, K comparable] interface {
~[]T | ~map[K]T
}
func Map[C Collection[T, K], T any, K comparable](collection C, callback func(item T) T) ([]T, map[K]T) {
switch t := any(collection).(type) {
case []T:
slice := make([]T, 0, len(collection))
for _, el := range t {
slice = append(slice, callback(el))
}
return slice, nil
case map[K]T:
hashMap := make(map[K]T, len(collection))
for key, el := range t {
hashMap[key] = callback(el)
}
return nil, hashMap
default:
return nil, nil
}
}
func main() {
list := []uint64{1, 2, 3, 4, 5}
person := make(map[string]string)
person["leha"] = "blevushkin"
person["dima"] = "kekin"
person["alex"] = "ssikin"
slice, _ := Map[[]uint64, uint64, string](list, func(item uint64) uint64 {
return item + 1
})
fmt.Printf("%T %v
", slice, slice)
_, hashMap := Map[map[string]string, string, string](person, func(item string) string {
return item + "!"
})
fmt.Printf("%T %v
", hashMap, hashMap)
}
Блин, не знаю. Прекрасно всегда обходился без них. Вроде как выглядит полезной фича. Но всегда задачи на go у меня писались под конкретный тип данных.
Я думаю надо подождать, посмотреть. Там со временем может и придумают наиболее подходящие юзкейсы, где абстракция будет более полезна, чем скорость. Например для каких то конфигов при запуске приложения.
наверно конечно можно обходится без них, но когда, например, пишешь какую ни будь структуру данных с ними красивее выглядит чем без них)
если пишешь библиотечный код без них тоже можно, но с ними будет проще…
так-то ясно понятно, что без них можно обойтись в некоторых случаях, например, через полиморфизм
очень прошу сделай шрифт побольше
Хорошо
Будут ли еще новые уроки?
Да, но через пару недель)
@@thisisit7267 Большое, большое спасибо за положительный ответ.)
@@thisisit7267 Привет, ждем тебя) Сервис был заявлен) Чистая архитектура, entities, usecases, adapters все дела)
@@ruauka Привет, я не пропал😅 Пилю видос, в эти выходные будет. Потом примерно через 2 недели, ибо командировки/отпуск)
В дженериках только одно хорошо, это то что они не нужны, когда нужен быстрый код
Без компромиссов не обошлось) Видимо тут придется выбирать между быстротой работы vs удобство/cкорость написания кода. Да и в целом создание доп. абстракций всегда накладывает некий оверхед
Кстати, Максим, если можно, прикрепите ссылки на бенчмарки, будет интересно посмотреть, ибо я тему производительности в видео не затрагивал)
Как на ютюбе оставлять ссылки?)) Сейчас попробую добавить если автомодерирование пропустит
В конце статьи можно увидеть bench. Сам глубоко не вникал, но в интернете их сравнивают с значением interface{}, прирост составляет от 10% до 20% в дженериках, правда аллокаций больше
"faster-sorting-with-go-generics" (можно быстро найти в гугле по названию статьи)
что то я поплыл
Благодарю за видео.
Но как по мне, от них только вред, теперь будут лепить кто во что горазд)
В целом да, много нового синтаксиса, код становится читать немного сложнее + влияние на производительность. Но идея конечно сама по себе довольно интересная)
non-comparable также функции, интерфейсы