diff --git a/README.md b/README.md index 38d6b6f..d1b8f22 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ pairing with smart people at Hashrocket. For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186). -_1558 TILs and counting..._ +_1559 TILs and counting..._ See some of the other learning resources I work on: - [Ruby Operator Lookup](https://www.visualmode.dev/ruby-operators) @@ -416,6 +416,7 @@ See some of the other learning resources I work on: - [Create A Slice From An Array](go/create-a-slice-from-an-array.md) - [Detect If Stdin Comes From A Redirect](go/detect-if-stdin-comes-from-a-redirect.md) - [Deterministically Seed A Random Number Generator](go/deterministically-seed-a-random-number-generator.md) +- [Difference Between Slice And Pointer To Slice](go/difference-between-slice-and-pointer-to-slice.md) - [Do Something N Times](go/do-something-n-times.md) - [Find Executables Installed By Go](go/find-executables-installed-by-go.md) - [Format Date And Time With Time Constants](go/format-date-and-time-with-time-constants.md) diff --git a/go/difference-between-slice-and-pointer-to-slice.md b/go/difference-between-slice-and-pointer-to-slice.md new file mode 100644 index 0000000..843a32c --- /dev/null +++ b/go/difference-between-slice-and-pointer-to-slice.md @@ -0,0 +1,55 @@ +# Difference Between Slice And Pointer To Slice + +Though a slice can be thought of and used as a flexible, variable-length +array-like data structure, it is important to understand that it is also a +special kind of pointer to an underlying array. + +This matters when we a function receives a slice versus a pointer to a slice as +an argument, depending on what it is doing with that slice. + +If the function is access or updating elements in the slice, there is no +difference. There is no meaningful difference between these two functions and +we might as well use the former. + +```go +func replaceAtIndex(slice []string, index int, value string) { + slice[index] = value +} + +func replaceAtIndexPtr(slice *[]string, index int, value string) { + (*slice)[index] = value +} +``` + +On the other hand, if the receiving function needs to append to or replace the +slice, then we need to pass a pointer to the slice. A direct slice argument +will result in only the function-local copy getting replaced. + +```go +package main + +import ( + "fmt" +) + +func main() { + s1 := []int{8, 6, 7, 9} + s2 := []int{8, 6, 7, 9} + + addItem(s1, 11) + fmt.Printf("s1: %v\n", s1) //=> s1: [8 6 7 9] + + addItemPtr(&s2, 11) + fmt.Printf("s2: %v\n", s2) //=> s2: [8 6 7 9 11] +} + +func addItem(slice []int, value int) { + slice = append(slice, value) +} + +func addItemPtr(slice *[]int, value int) { + (*slice) = append(*slice, value) +} +``` + +[source](https://go.dev/tour/moretypes/8)