Předá se mělká kopie.
Slice je syntax suggar, viz link od Calculona. Chová se jako struct, ale může nabývat `nil` hodnoty :/
V Go 0.x se map, také syntax suggar, zapisovala s hvězdičkou, aby bylo jasné, že se předává pointer. Ale jelikož neexistovalo využití bez hvězdičky, tak se od toho upustilo.
Slices jsou celkem spolehlivý zdroj bugů. Stačí aby někdo naivně spoléhal, že append alokuje nové array. Nebo editovat slice s tím, že tu starou proměnnou už nikdo nepoužije. A další.
To ne, žádné pole se neuvolní, dokud na něj existují reference. Ale některé knihovny dělají z řetězců řezy bajtů bez kopírování a když je řetězec konstantní, je v neměnitelném segmentu paměti, proto crash při pokusu o změnu. Jde to proti sémantice jazyka, ale někdo to dělá pomocí unsafe kvůli efektivitě (a pak se diví).
Append primárně přidává prvek do slice. Nové pole alokuje az kdyz je to soucasné nedostatečné. Dělá to klasickým algoritmem, že se prealokuje dvojnásobné pole, a zkopíruje obsah predchozího.
To, že append nevytváří pokaždé nové pole je hezky využitelné.
Třeba když dělam filter na slice, a vím, že ten výskyt prvku, který budu odebírat, je minimální, tak prealokuji slice s plnou kapacitou, ale nulovou délkou.
https://go.dev/play/p/dYAOoZ6rMxJ
Jo, tohle je standard, co dělají všichni. vector v C++, Listy v C# atd...
Go k tomu akorát přidává nečekané chování v tom, že stejný kontejner umí i slicing a to bez běžných řešení typu COW. Takže je jednoduché dostat dva slicy, které se při přidávání budou bít o jedno "prázdné" místo na konci.
Tohle je hezky využitelné tak akorát na barvení vlasů na šedo. ;)