Илья
обычно, тут всплывает пример с append, где игнорируется реаллокация
Valentin
Вообще да, слайсы передаются по ссылке
Anonymous
Вообще да, слайсы передаются по ссылке
если б по ссылке, то все операции со слайсом меняли бы старый слайс, но есть какие-то операции, которые этого не делают
Anonymous
щас проверю append
Valentin
Честно говоря ни разу не встречался
Anonymous
https://play.golang.org/p/hsyjmQLdsP
Anonymous
блэт, перестало по ссылке передаваться
Vladimir
Ответы на такие вопросы приходят проще если понимать что происходит
Vladimir
И что такое слайс
Илья
https://golang.org/pkg/reflect/#SliceHeader
Anton
какая аргументация насчет возврата func getAll() []Test заместо func getAll() *[]Test ?
Илья
https://play.golang.org/p/RlBUNtxlXH
Илья
у меня скорее вопрос, какая аргументация за *[]Test, если []Test норм?
Anonymous
https://play.golang.org/p/RlBUNtxlXH
Теперь я ещё больше удивлён.
Vladimir
https://golang.org/src/runtime/slice.go
Vladimir
11 строка
Vladimir
у меня скорее вопрос, какая аргументация за *[]Test, если []Test норм?
Если ты хочешь менять оригинальный слайс в семантике сей
Vladimir
Например аппенд, а не изменение элемента будет делать на слайс не то что ты ожидаешь, передав его по ссылке
Vladimir
А дальше вопрос - ты будешь возвращать новый слайс или просто менять старый
Anton
у меня скорее вопрос, какая аргументация за *[]Test, если []Test норм?
товарищ написал изначально *[]Test. И сказал, что заменит на что угодно другое, только после аргументации :D
Илья
Теперь я ещё больше удивлён.
почему? ты получаешь копию структуры с указателем на общие данные, когда ты присваешь ему nil, ты сбрасываешь свой указатель, но это не аффектит исходные данные, но, если ты изменяешь данные, то операцию происходят над теми же данными
Vladimir
Аргумент же
Anonymous
func TestSomeTest(t *testing.T) { s := []int{1,2,3} func(d []int){ d = append(d, 4) }(s) log.Println(s) } результат 1,2,3 если б "по ссылке", то 1,2,3,4
Vladimir
append, в данном случае аллоцирует новый slice
Если у тебя cap больше Len - не алоцирует
Vladimir
Замени на make([]int, 0, 10)
Anonymous
append, в данном случае аллоцирует новый slice
есть аналогичная по функциональности append операция, которая не аллоцирует?
Илья
Если у тебя cap больше Len - не алоцирует
это да, я писал про этот конкретный кейс
Vladimir
В том же коде
Vladimir
Будет тот же результат
Anonymous
func TestSomeTest(t *testing.T) { s := make([]int, 10) s[0] = 1 s[1] = 2 s[2] = 3 func(d []int){ d = append(d, 4) }(s) log.Println(s) } [1 2 3 0 0 0 0 0 0 0]
Мерль
есть аналогичная по функциональности append операция, которая не аллоцирует?
Если у тебя ёмкость слайса больше чем длина, то аллокации не происходит
Valentin
Блин я уже забыл про эти особенности
Anonymous
Не ", 10", а "0, 10"
index out of range тогда
Oleg
Так не изменится же ничего. Как выводило 1, 2, 3, так и будет выводить
Valentin
Действительно, если cap хватает аллокации не будет
Vladimir
index out of range тогда
Так добавлять аппендом
Илья
index out of range тогда
вы, видимо, совсем плохо с slice разобрались, для вашего примера make([]int,3,10)
Илья
или все данные добавлять append
Anonymous
вы, видимо, совсем плохо с slice разобрались, для вашего примера make([]int,3,10)
для обоих предложенных результатов s всё равно [1 2 3]
Anonymous
в логе
Valentin
Покажи код
Anonymous
что так: func TestSomeTest(t *testing.T) { s := make([]int,3, 10) s[0] = 1 s[1] = 2 s[2] = 3 func(d []int){ d = append(d, 4) }(s) log.Println(s) }
Oleg
Что и есть ожидаемо :)
Я вообще не понимаю, о чем речь :)
Anonymous
что так: func TestSomeTest(t *testing.T) { s := make([]int, 0, 10) s = append(s, 1) s = append(s, 2) s = append(s, 3) func(d []int){ d = append(d, 4) }(s) log.Println(s) }
Anonymous
Что и есть ожидаемо :)
как же? ведь без реаллокации мы должны были поменять исходный слайс, как я понял и получить 1 2 3 4
Vladimir
Я вообще не понимаю, о чем речь :)
О том что копируется слайс не так очевидно при передаче в функцию
Anonymous
парни, если я в функции main запускаю поток(go parser()), то каким образом сделать так, чтобы программа не отстанавливалась пока выполняется поток?
Vladimir
При передаче его в функцию
Vladimir
Происходит копирование структуры слайса
Vladimir
Указателя на функцию
Vladimir
Капа и лен
Vladimir
Ты меняешь Len нового слайса
Oleg
как же? ведь без реаллокации мы должны были поменять исходный слайс, как я понял и получить 1 2 3 4
Аллокации не будет, но слайс вернётся новый. Просто он будет указывать не на 3 байта в памяти, а на 4.
Vladimir
Но при этом первые три элемента ты можешь менять
Vladimir
И если ты залезешь внутрь старого слайса и поменяешь ему только Len на 4, то там тоже найдешь свой новый элемент
Vladimir
Я вообще не понимаю, о чем речь :)
Кстати оффтоп, но у меня дома такой же кот как у тебя на аватврке, только без банки
Anonymous
Но при этом первые три элемента ты можешь менять
это я знаю. разница с мапой, что с ней любые операции меняют изначальную мапу. а со слайсом это не так
Valentin
Смысл спорить, обратимся у официальному источнику https://blog.golang.org/go-slices-usage-and-internals
Anonymous
Уши растут от того что такое внутри есть слайс и мапа
это понятно, просто всё это сводится к тому, что если нужно редактировать слайс, его надо передавать по указателю, в общем случае
Oleg
Кстати оффтоп, но у меня дома такой же кот как у тебя на аватврке, только без банки
Подарите своему коту банку, чего же он такой обделенный
Valentin
А не лучше вернуть слайс в return?
Anonymous
ну или так
Anton
короче, мапы можно передавать без *, если я туда в функции хочу напихать еще мульён значений ?
Valentin
Верни в функции слайс и все
Anonymous
у меня есть код, который римерно 32млн значений пихает в мапу и читает из нее на протяжении разлиичных вызовов в скрипте