Чтобы добавить к комментарию @ icza , вы можете легко извлечь базовый массив, используя &data[0]
- предполагая, data
- инициализированный фрагмент. Здесь нет необходимости перепрыгивать через обручи: адрес элемента первого среза фактически является адресом первого слота в базовом массиве среза - здесь нет никакой магии.
Поскольку получение адреса элемента массива создает
ссылка на эту память - до тех пор, пока сборщик мусора
обеспокоен - вы можете спокойно позволить самому срезу выйти из области видимости
без страха, что память этого массива станет недоступной.
Единственное, что вы не можете сделать с
указатель проходит вокруг результата разыменования.
Это просто потому, что массивы в Go имеют свою длину, закодированную в
их тип, поэтому вы не сможете создать функцию для принятия
такой массив - потому что вы заранее не знаете длину массива.
Теперь, пожалуйста, остановитесь и подумайте.
После извлечения резервного массива из среза у вас есть
указатель на память массива.
Чтобы разумно носить его, вам также нужно носить с собой
длина массива ... но это именно то, что делают срезы:
они упаковывают адрес резервного массива с длиной
данные в нем (а также емкость).
Следовательно, на самом деле я думаю, что вы должны пересмотреть свою проблему
с того места, где я стою, я склонен думать, что это не проблема
для начала.
Есть случаи , в которых используются указатели на массивы поддержки.
извлеченные из кусочков могут помочь: например, при «объединении»
такие массивы (скажем, через sync.Pool
), чтобы уменьшить отток памяти
в определенных ситуациях, но это конкретные проблемы.
Если у вас есть конкретная проблема, пожалуйста, объясните ,
не твоя попытка решить эту проблему - что сказал @Flimzy.
Обновление Я думаю, что я должен быть лучше объяснить
вы не можете сделать с
указатель проходит вокруг результата разыменования.
немного.
Критический момент о массивах в Go (в отличие от срезов)
что массивы - как и все в Go - передаются
по значению и для массивов, что означает, что их данные копируются.
То есть, если у вас есть
var a, b [8 * 1024 * 1024]byte
...
b = a
утверждение b = a
действительно скопирует 8 МБ данных.
То же самое относится и к аргументам функций.
Ломтики обходят эту проблему, удерживая указатель
в базовый (резервный) массив. Так что значение среза
это маленький struct
тип, содержащий
указатель и два целых числа.
Следовательно копирование это действительно дешево, но "взамен" это
имеет ссылочную семантику: исходное значение и
его точка копирования в том же массиве поддержки, то есть
ссылаться на те же данные.
Я действительно советую вам прочитать эти две части,
в указанном порядке:
- https://blog.golang.org/go-slices-usage-and-internals
- https://blog.golang.org/slices