From 5e19d53382e1511036e08ddb6d46ef9192da478c Mon Sep 17 00:00:00 2001 From: jbranchaud Date: Sun, 29 Dec 2024 10:26:55 -0700 Subject: [PATCH] Add Pass A Struct To A Function as a Go TIL --- README.md | 3 +- go/pass-a-struct-to-a-function.md | 65 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 go/pass-a-struct-to-a-function.md diff --git a/README.md b/README.md index a7e85c8..3307066 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). -_1551 TILs and counting..._ +_1552 TILs and counting..._ --- @@ -415,6 +415,7 @@ _1551 TILs and counting..._ - [Not So Random](go/not-so-random.md) - [Parse A String Into Individual Fields](go/parse-a-string-into-individual-fields.md) - [Parse Flags From CLI Arguments](go/parse-flags-from-cli-arguments.md) +- [Pass A Struct To A Function](go/pass-a-struct-to-a-function.md) - [Produce The Zero Value Of A Generic Type](go/produce-the-zero-value-of-a-generic-type.md) - [Redirect File To Stdin During Delve Debug](go/redirect-file-to-stdin-during-delve-debug.md) - [Replace The Current Process With An External Command](go/replace-the-current-process-with-an-external-command.md) diff --git a/go/pass-a-struct-to-a-function.md b/go/pass-a-struct-to-a-function.md new file mode 100644 index 0000000..70d6ad7 --- /dev/null +++ b/go/pass-a-struct-to-a-function.md @@ -0,0 +1,65 @@ +# Pass A Struct To A Function + +Go operates as _pass-by-value_ which means that when we pass a struct to a +function, the receiving function gets a copy of the struct. Two things worth +noticing about that are 1) an extra memory allocation happens when calling the +function and 2) altering the struct does not affect the original in the calling +context. + +On the other hand, we can have a function that takes a pointer to a struct. +When we call that function, we have a reference to the memory location of the +struct instead of a copy of the struct. That means no additional allocation and +modifications to the dereferenced struct are modifications to the original in +the calling context. + +Here is an example that demonstrates both of these. Notice the printed output +that is included in comments at the end which shows memory locations and +contents of the struct at various points. + +```go +package main + +import "fmt" + +type Order struct { + Item string + Quantity int + DineIn bool +} + +func main() { + order := Order{Item: "taco", Quantity: 3, DineIn: true} + + fmt.Println("Order:", order) + fmt.Printf("main - Loc: %p\n", &order) + + doubledOrder := doubleOrder(order) + + fmt.Println("Double Order:", doubledOrder) + fmt.Println("Original Order:", order) + + doubleOrderPtr(&order) + + fmt.Println("Double Order Ptr:", order) +} + +func doubleOrder(order Order) Order { + fmt.Printf("doubleOrder - Loc: %p\n", &order) + order.Quantity *= 2 + + return order +} + +func doubleOrderPtr(order *Order) { + fmt.Printf("doubleOrderPtr - Loc: %p\n", order) + (*order).Quantity *= 2 +} + +// Order: {taco 3 true} +// main - Loc: 0xc0000b4000 +// doubleOrder - Loc: 0xc0000b4040 +// Double Order: {taco 6 true} +// Original Order: {taco 3 true} +// doubleOrderPtr - Loc: 0xc0000b4000 +// Double Order Ptr: {taco 6 true} +```