Call by value와 Call by reference
Call by value
type a struct {
value int
}
func run(aa,bb a) {
aa.value = 111
bb = aa
fmt.Println(aa, bb)
}
func main() {
a1 := a{value: 1}
a2 := a{value: 2}
run(a1,a2)
fmt.Println(a1, a2)
}
결과
{111} {111}
{1} {2}
- run 함수 내부에서는 변경이 되지만 외부까지 변경이 전파가 되진 않는다.
- 그 이유는 run 함수 내부의 파라미터가 실제 객체를 복사한 값을 사용하기 때문
- 이 방식이 Call by Value 다
Call by reference
- 하지만 Go 에서는 Call By Value 대신 Call By Referece도 사용할 수 있는데
- 그 방법은 바로 Pointer를 사용하는 방법이다
type a struct {
value int
}
func run(aa,bb *a) {
aa.value = 111
bb = aa
fmt.Println(aa, bb)
}
func main() {
a1 := a{value: 1}
a2 := a{value: 2}
run(&a1,&a2)
fmt.Println(a1, a2)
}
결과
&{111} &{111}
{111} {2}
- run 함수 내부의 변경이 외부까지 전파가 되었다.
- 하지만 bb 파라미터의 변경은 외부에 전파가 되지 않았다. 그 이유는 뭘까 ?
- 내부 파라미터 자체를 변경했기 때문이다.
- 실제 객체를 변경하는 것이 아닌 파라미터에 할당한 값이 bb의 주소에서 aa의 주소로 변경 된것일 뿐이다.
- 하지만 bb 파라미터의 변경은 외부에 전파가 되지 않았다. 그 이유는 뭘까 ?
자바와 다른점
- java는 Call by value 지만 객체를 넘겼을 경우 객체 내부의 변경이 외부에 전파가 된다.
- 이는 파라미터로 객체를 전달시에 객체의 주소를 넘기기 때문이다.
- 주소를 넘김으로써 주소가 가리키는 객체가 외부의 객체가 되고 변경의 여파가 외부까지 전파되는 것이다.
파라미터에 Pointer를 사용하는 경우
- 보통 Pointer를 사용시 내부에서의 변경이 외부까지 전파가 되므로 최대한 사용을 자제하는 방향이다.
- 하지만 객체가 생성비용이 비싼 경우 Call by value로 복사를 하므로 생성비용이 과하게 나오는 경우가 생긴다.
- 이런 경우 Pointer를 사용하여 객체 생성비용을 절약할 수 있다.