Go lang 실습

golang: slice & array

컴닥 2021. 8. 12. 08:15
반응형

go는 call by value만 지원합니다. 
call by reference와 비슷하게 쓰려면 포인터 값을 전달하면 됩니다. 

array는 당연히 call by value 방식으로 작동합니다. 
그것만 지원하니까요.. 

package main

import "fmt"

func addOne(arr [4]int) {
	for i := range arr {
		arr[i]++
	}
	fmt.Println("addOne:", arr)
}

func main() {
	a := [4]int{1, 2, 3, 4}
	addOne(a)
	fmt.Println("main:", a)
}
addOne: [2 3 4 5]
main: [1 2 3 4]

상식적입니다. 

위에서 언급한데로 포인터를 이용해서 call by reference 비슷하게 사용해 봅시다.

package main

import 	"fmt"

func addOne(arr *[4]int) {
	for i := range arr {
		arr[i]++
	}
	fmt.Println("addOne:", arr) //
}

func main() {
	a := [4]int{1, 2, 3, 4}
	addOne(&a)
	fmt.Println("main:", a)
}
addOne: &[2 3 4 5]
main: [2 3 4 5]

잘 작동합니다. 
"addOne: &[2 3 4 5]" 이 부분이 재미있으면서 거슬리네요.. 

이렇게 쓸 수도 있겠죠.

package main

import "fmt"

func addOne(arr *[4]int) {
	for i := range *arr { //
		arr[i]++
	}
	fmt.Println("addOne:", *arr) //
}

func main() {
	a := [4]int{1, 2, 3, 4}
	addOne(&a)
	fmt.Println("main:", a)
}
addOne: [2 3 4 5]
main: [2 3 4 5]

잘 작동합니다. 


"for i := range *arr {" 이 부분도 재미있습니다. 
"for i := range arr {" 와 똑같이 작동하네요. 

 

반면 슬라이스란 배열의 포인터에 길이, 용량이 추가된 구조체 라고 볼 수 있기 때문에... 
(슬라이스란 포인터가 본질이기 때문에)
call by value를 해도 포인터 값이 들어가 버리는 군요. 

package main

import "fmt"

func addOne(arr []int) {
	for i := range arr {
		arr[i]++
	}
	fmt.Println("addOne:", arr)
}

func main() {
	a := []int{1, 2, 3, 4}
	addOne(a)
	fmt.Println("main:", a)
}
addOne: [2 3 4 5]
main: [2 3 4 5]

 

모양은 비슷하지만 이런 차이가 있습니다. 

반응형