Как работать с указателями на массивы (слайсы) в GO (golang)?

Привет!
Вот уже целых 2 дня я изучаю GO, запилил простую программку строк на 200. Ни о какой красоте в ней речи не идет, но "на попробовать" в самый раз.
Очень понравились гору́тины (или го́рутины или горути́ны - некому подсказать кака это правильно называется).
Как обдж-си_шника меня смутило отсутствие массивов с произвольным размером. (Так же смутило наличие "слайсов" - требует дополнительного разбирательства) Решено было запилить функцию append, которая принимала бы массив и то что в него надо запихнуть под экстраиндексом (эх дженерики, дженерики...). Хотелось бы что бы эта функция принимала не сам массив а только указатель на него, но тут же возникает проблема: указатель на массив получен а вот len(этого_массива) получить уже не возможно - len не принимает указатель. Подскажите как тут быть?
Может я вообще не в том направлении копаю? Может есть где-то в го-недрах массивы произвольной длинны?
  • Вопрос задан
  • 10114 просмотров
Решения вопроса 1
@localghost
Я примерно на вашем же уровне в Go, но вот что я себе представляю: слайсы и есть "изменяемые массивы" для наших целей. На деле это ссылки на массивы, которые все равно неизменны, но если мы хотим изменить размер слайса, то мы просто получим новый underlying массив и ссылку на него.
Для слайсов вполне себе есть встроенная функция append:
s0 := []i n t {0, 0}
s1 := append(s0, 2)
s2 := append(s1, 3, 5, 7)
s3 := append(s2, s0...)

P. S. Почти все, что изучал я, - вот эта книжка: www.miek.nl/downloads/Go/Learning-Go-latest.pdf
P. P. S. Горутины, думаю, читаются как го́-рути́ны, с основным вторым ударением :)
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
index0h
@index0h
PHP, Golang. https://github.com/index0h
Юзайте слайсы, это ссылочный тип. Если размер выйдет за рамки емкости - внутренний массив слайса будет пересоздан с большей емкостью.

В принципе можете еще посмотреть golang.org/pkg/container
Ответ написан
uvelichitel
@uvelichitel Куратор тега Go
habrahabr.ru/users/uvelichitel
origArray := []string{"1", "2"}  //уже дает вам слайс, а не массив
origSlice := origArray[:]   //в этой строке нет никакого смысла
//массив можно получить так 
var myArray [2]string = [2]string{"1", "2"}

Слайс в Go - ссылочный тип. Объект этого типа содержит три атрибута len длину Int, cap поместительность Int и указатель на первый элемент Pointer.
Все аргументы в Go передаются копированием значения, то есть передавая функции слайс вы передаете копию слайса. Эта копия будет содержать собственные len и cap, но однако указатель на тот же первый элемент что и аргумент. Таким образом, чтобы модифицировать элементы слайса достаточно передать его функции, чтобы защитить слайс от модификации функцией нужно передавать его копию сделанную встроенной функцией copy(dst, src) Чтобы дать функции доступ к длине len и вместительности cap слайса следует передавать указатель на него. append очевидно требует изменения не только элементов но и длины и вместительности слайса поэтому передавать нужно указатель на слайс.
foo(&origSlice){
*origSlice = append(* origSlice, "3")
...

Однако осторожней
foo (origSlice){
origSlice[1]="baz"
...
}

изменит оригинальный origSlice, хотя и не может изменить его длину
Ответ написан
@Flie Автор вопроса
index0h: Что-то у меня не очень получается. Давайте я вам попробую своими словами объяснить что нужно а вы, если есть возможность, покажете как это делается в GO.
a0eba72060b14541afe83a722e292f4b.png
На первой картинке то, как можно работать с указателями в свифте.
На 2ой - то как я пытаюсь это сделать в ГО.
f7359c0c697a4ace8c82dd76a40d6805.png
В консоли -
[1 2]
[1 2]

если передавать как &/* то ошибка на append
Подскажите что не так?
Ответ написан
DoZat0r
@DoZat0r
iOS/ OS X Developer
Доброго времени суток.

Как вам и писали ранее в этой строке смысла нет: origSlice := origArray[:]

А вообще решение таково:

98bfaddb9dd842828c22bad7ce58ce29.png
Ответ написан
Комментировать
@Wasghen
Весьма хорошее объяснение в этом видео - https://youtu.be/1vAIvqDo5LE
Рассказывает о том, что такое слайс под капотом
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы