Help for the VSCode editor.
-
What would be the output of the following program:
Note: add package and import statements as needed
func modify(numbers ...int) { for i := range numbers { numbers[i] -= 5 } } func main() { arr := []int{10, 20, 30} fmt.Println(arr) modify(arr...) fmt.Println(arr) }
- [10 20 30]
[5 15 25] - [10 20 30]
[10 20 30] - [10 20 30]
[15 25 35] - Error
Reveal
[10 20 30]
[5 15 25]- Create a slice of
int
with 3 values - Print it
- Call the function
modify
which takes a variadic argument. The slice is passed by reference, meaning that if it modifies the values in the slice, then the caller sees the change. Slice data is always passed by reference as they behave like pointers. - Hence in the final
Println
we see that 5 has bee subtracted from all values.
- [10 20 30]
-
What would be the output of the following program:
Note: add package and import statements as needed
func modify(numbers [3]int) { for i := range numbers { numbers[i] -= 5 } } func main() { arr := [3]int{10, 20, 30} fmt.Println(arr) modify(arr) fmt.Println(arr) }
- [10 20 30]
[5 15 25] - [10 20 30]
[10 20 30] - [10 20 30]
[15 25 35] - Error
Reveal
[10 20 30]
[10 20 30]- This time an array has been declared, not a slice
- Arrays are passed by value, therefore the
modify
function receives a copy of the array. The caller's array is not modified.
- [10 20 30]
-
What would be the output of the following program:
Note: add package and import statements as needed
func modify(numbers *[3]int) { for i := range numbers { numbers[i] -= 5 } } func main() { arr := [3]int{10, 20, 30} fmt.Println(arr) modify(arr) fmt.Println(arr) }
- [10 20 30]
[5 15 25] - [10 20 30]
[10 20 30] - [10 20 30]
[15 25 35] - Error
Reveal
Error
- The program will not compile since the
modify
function expects a pointer to an array of[3]int
. - The call
modify(arr)
is passing the array itself, not a pointer to it.
- [10 20 30]
-
What would be the output of the following program:
Note: add package and import statements as needed
func modify(s *string) { *s = strings.ToUpper(*s) } func main() { s := "hello" fmt.Println(s) modify(&s) fmt.Println(s) }
- hello HELLO
- hello
HELLO - HELLO hello
- hello
Reveal
hello
HELLOYou must add
strings
as an import to useToUpper
- Initialize a string variable
s
with valuehello
, then print it. - The
modify
function takes a pointer to string, converts the value it is pointing to to upper case, then stores the conversion back in the variable being pointed to, i.e. it will modify the caller's variable. main
callsmodify
passing the address of the variables
- i.e. providing a pointer tos
- Print the end result, which is now upper cased.
- There is a newline in the output because
Println
was called twice andPrintln
always appends a newline.
-
What would be the output of the following program:
Note: add package and import statements as needed
func modify(s map[string]int) { s["A"] = 100 } func main() { ascii_codes := map[string]int{} ascii_codes["A"] = 65 fmt.Println(ascii_codes) modify(ascii_codes) fmt.Println(ascii_codes) }
- map[A:65]
map[A:65] - map[A:65]
map[A:100] - [A:65]
[A:100] - [A:65]
[A:65]
Reveal
map[A:65]
map[A:100]- When a map is printed, it is always printed like
map[...]
so two answers can be ruled out immediately. - Maps are always passed by reference in function calls, therefore
modify
will modify theascii_codes
map and the modification is seen in the second print.
- map[A:65]
-
Wrap up
- Slices and maps are always passed by reference so they behave like pointers to the caller's data when used as function arguments. If a function modifies a slice or a map argument, the change will affect the caller.
- All other types, including arrays are passed by value (a copy is made for the function to use). If you want a function to be able to modify the caller's variable, then you must use a function that takes a pointer argument like Q4, and pass the address of your variable (
&
operator) to the function. - When using or modifying the value being pointed to in the function, you use the dereference operator (
*
).