Go 포인터 정리
2021-04-18 11:43:08

포인터가 익숙치 않기 때문에.. 다시 정리를 해 보았다 🤔

변수에서 사용하는 경우

일반 변수에서 사용하는 경우

1
2
3
4
5
6
7
8
9
var age uint16 = 34 // age에 34라는 값을 할당 하였다.
func main() {
fmt.Println("age is", age) // age is 34
ageAddr := &age // &기호를 붙여서 age의 주소값을 할당할 수 있다
fmt.Println("ageAddr is", ageAddr) // ageAddr is 0x1149182
fmt.Println("ageAddrValue is", *ageAddr) // *기호를 붙여서 age 주소에 속해 있는 값을 알 수 있다 ageAddrValue is 34
*ageAddr = 19 // 주소에 속한 값을 변경 하므로 age 또한 변경 된다
fmt.Println("age is", age) // age is 19
}

구조체 변수에서 사용하는 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
type User struct {
id *uint // 구조체의 변수에 *기호를 붙이면 주소값을 할당할 수 있다
name string
}

func main() {
var user = User{}
var idAddr uint = 1
user.id = &idAddr // id 변수에 주소값 할당
user.name = "delryn"
fmt.Println("user is", user) // user is {0xc000014080 delryn}
fmt.Println("user id is", *user.id) // user id is 1
}

함수에서 사용하는 경우

매개변수의 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

type User struct {
id uint
name string
}

func main() {
var arg uint16 = 10
var arg2 uint16 = 100
pointerFunc(&arg) // arg의 주소값을 인수로 넘긴다
fmt.Println("final arg is", arg) // final arg is 30
normalFunc(arg2)
fmt.Println("final arg2 is", arg2) // final arg2 is 100

user := User{}
user.id = 1
user.name = "delryn"
fmt.Println("init user is ", user) // init user is {1 delryn}
structTest(&user) // 구조체의 주소값을 인수로 넘긴다
fmt.Println("final user is", user) // final user is {2 delryn}
}

func pointerFunc(param *uint16) { // 데이터 타입에 *기호를 붙임으로서 주소값을 매개변수로 받는다고 설정
fmt.Println("pointerFunc paramAddr is", param) // pointerFunc paramAddr is 0xc0000ae002
fmt.Println("paramValue is", *param) // paramValue is 10
*param += 20 // 매개변수여도 주소에 속한 값을 변경 하면 원본 arg의 값이 바뀌는 건 변함 없다
}

func normalFunc(param uint16) { // 일반 함수의 경우 매개변수는 복사 되어서 넘어 오기 때문에 값을 변경 해도 원본 값 arg2는 변경이 안 된다
fmt.Println("normalFunc param is", param) // normalFunc param is 100
param += 200
}

func structTest(user *User) { // 구조체의 경우에도 변수와 동일하게 *기호를 붙이면 된다
user.id = 2
fmt.Println("test user is ", user) // test user is &{2 delryn}
}

리턴 값의 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
type User struct {
id uint
name string
}

func main() {
var arg uint16 = 30
result := receivePointerFunc(arg)
fmt.Println("receivePointerFunc result is", result) // receivePointerFunc result is 0xc000122002
fmt.Println("receivePointerFunc resultValue is", *result) // receivePointerFunc resultValue is 40
fmt.Println("final arg is", arg) // final arg is 30

var arg2 uint16 = 10
result = receivePointerFunc2(&arg2)
fmt.Println("receivePointerFunc2 result is", result) // receivePointerFunc2 result is 0xc000122004
fmt.Println("receivePointerFunc2 resultValue is", *result) // receivePointerFunc2 resultValue is 110
fmt.Println("final arg2 is", arg2) // final arg2 is 110

var arg3 uint16 = 30
result2 := normalFunc(arg3)
fmt.Println("normalFunc result addr is", &result2) // normalFunc result addr is 0xc000122006

var user = User{}
user.id = 1
user.name = "delryn"
fmt.Println("user is", user)
result3 := receiveStructPointerFunc(user) // user is {1 delryn}
fmt.Println("receiveStructPointerFunc result is", result3) // receiveStructPointerFunc result is &{2 delryn}
fmt.Println("final user is", user) // final user is {1 delryn}
}

func receivePointerFunc(param uint16) *uint16 { // 리턴하는 데이터 타입에 *기호를 붙여서 포인터를 리턴한다고 표현
fmt.Println("receivePointerFunc param is", param) // receivePointerFunc param is 30
param += 10 // param의 경우 복사된 값이기 때문에 원본 arg 값에 영향이 없다
fmt.Println("receivePointerFunc param addr is", &param) // receivePointerFunc param addr is 0xc000122002
return &param // 주소값을 리턴 해야 한다
}

func receivePointerFunc2(param *uint16) *uint16 {
fmt.Println("receivePointerFunc2 param is", param) // receivePointerFunc2 param is 0xc000122004
*param += 100 // 주소에 속한 값에 + 100을 해준 거기 때문에 원본 arg2의 값이 변경 된다
return param // 이미 매개변수가 주소값이기 때문에 &기호를 붙일 필요가 없다
}

func normalFunc(param uint16) uint16 {
param += 10
fmt.Println("normalFunc param addr is", &param) // normalFunc param addr is 0xc000122008
return param // 리턴 값도 복사해서 넘기는거기 때문에 주소 값이 변경되는 걸 확인할 수 있다
}

func receiveStructPointerFunc(user User) *User {
user.id += 1
fmt.Println("receiveStructPointerFunc user is", user) // receiveStructPointerFunc user is {2 delryn}
return &user
}

구조체 메서드의 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
type Cal struct {
x int
y int
result int
}

func (c Cal) plus() int {
c.result += c.x + c.y
return c.result
}

func (c *Cal) plus2() int {
c.result += c.x + c.y
return c.result
}

func main() {
a := Cal{x: 1, y: 1}
fmt.Println(a.plus()) // 2
fmt.Println(a.plus()) // 복사가 되기 때문에 결과값이 누적이 되질 않는다, 2
b := Cal{x: 1, y: 1}
fmt.Println(b.plus2()) // 2
fmt.Println(b.plus2()) // 주소에 속한 값에 더하기 때문에 누적이 된다, 4
}
Prev
2021-04-18 11:43:08
Next