이 글은 골든래빗 《Tucker의 Go 언어 프로그래밍》의 14장 써머리입니다.
타입
p = &a
포인터 변수 p에 a의 주소를 대입하는 구문
포인터
라고 한다.*
를 붙여 선언한다.var p *int
var f *float64
var u *User
...
p는 int 타입 데이터의 메모리 주소를 가리키는 포인터 변수이다.
포인터 변수에 값을 채우려면 데이터 앞에 &
를 붙여 메모리 주소를 받아와야 한다.
var a int
var p *int
p = &a //a의 메모리 주소를 포인터 변수 p에 대입한다.
*p = 1
t.Log(a, *p) //1 1
a = 3
t.Log(a, *p) //3 3
t.Log(&a == p) // 주소값
var a int
var p *int
p = &a //a의 메모리 주소를 포인터 변수 p에 대입한다.
t.Log(&a == p) //true
func valueChanger(num int) {
num = 1
}
func valueChangerWithPointer(num *int) {
*num = 1
}
func Test_pointerCopy(t *testing.T) {
var a int
valueChanger(a) //a의 값만 복사를 해가기 때문에 num 변수의 주소와 a 변수의 주소는 다름!
t.Log(a) //0
valueChangerWithPointer(&a) //a변수가 저장된 주소값을 가져가 그 주소에 저장된 값을 변경하기에 값이 변경된다.
t.Log(a) //1
}
//기존방식
var data Data
var p *Data = &data
//구조체를 생성해 초기화하는 방식
var p *Data = &Data{}
var data Data //Data 타입값을 저장할 메모리 공간 할당
var p *Data = &data //data의 주소만 가지고있기 때문에 메모리 공간 할당하지 않음
var p1 *Data = &Data{}
var p2 = p1
var p3 = p1 //인스턴스는 하나다.
var data1 Data
var data2 Data = data1
var data3 Data = data1 //모두 다른 인스턴스이다.
p1 := &Data{} //&를 사용하는 초기화
p2 := new(Data) // new()를 사용하는 초기화
Garbage Collector
라는 기능이 있는데, 메모리에서 쓸모없어진 데이터를 청소한다.func TestFunc() {
u := &User{] // u 포인터 변수를 선언하고 인스턴스 생성
u.Age = 30
fmt.Println(u)
} // 내부 변수 u가 사라지고 인스턴스도 사라진다.
가비지컬렉터 또한 비용이 많이 들어간다.
정리
- 인스턴스는 메모리에 생성된 데이터의 실체
- 포인터를 이용해 인스턴스를 가리키게 할 수 있다.
- 함수 호출 시 포인터 인수를 통해 인스턴스를 입력받고 그 값을 변경할 수 있게 된다.
- 쓸모 없어진 인스턴스는 가비지 컬렉터가 자동으로 지워준다.
escape analysis
)를 해서 어느 메모리에 할당할지 결정.dangling
) 오류가 발생한다.type User struct {
Name string
Age int
}
func NewUser(name string, age int) *User {
var u = User{name, age}
return &u // 탈출 분석을 통해 메모리가 사라지지 않는다.
}
func main() {
userPointer := NewUser("Coen", 34)
fmt.Println(userPointer)
}