Кастование произвольного слайса, к слайсу интерфейсов

Всем привет.


У каждого, кто знаком с Go был вопрос, а какого лешего я не могу сделать вот так вот:


var  a = []int{1,2,3}
b = []interface(a)

Почему приходится писать вот так:


b := make([]interface{}, len(a))
for i:=0; i<len(a); i++ {
   b[i] = a[i]
}

Но, можно и по другому....


Я решил немного размяться и найти способ сделать это быстрее и удобнее. Получилось.


Подробности здесь.


Если коротко, то благодаря пакету unsafe удалось заменить создание слайса интерфейсов и копирование данных, созданием слайса интерфейсов с len и cap оригинального слайса и копирование указателей. Благодаря особенностям реализации интерфейсов, получился, в нагрзуку, бесплатный(но не полноценный) механизм COW (copy-on-write): пока вы не изменяете данные в итоговом слайсе данные в исходном и результирующем слайсе лежат в одном месте, но при изменении элементов результирующего слайса этот элемент уже не будет указывать на исходный. В обратном порядке, к сожалению, это не работает.


Немножко о производительности:
Эффективность решения напрямую зависит от размера элементов слайса и длинны слайса, чем больше длинна слайса и "вес" элемента — тем эффективнее


https://gist.github.com/t0pep0/af41fba259eb4d3d00d2e7efa0e4093a

04/21/2017 18:45:37
0

комментарии (0)