🔥 포인터

389자
5분

Go 언어는 포인터를 지원하는데요. 포인터는 값의 메모리 주소를 가지고 있어요.

  • T 타입은 T 값에 대한 포인터예요. 포인터의 기본값은 nil이에요.
go
var p *int
 
go
var p *int
 

& 연산자는 피연산자에 대한 포인터를 생성한답니다.

go
i := 42
p = &i
 
go
i := 42
p = &i
 
  • 연산자는 포인터가 가리키는 값을 나타내요.
go
fmt.Println(*p) // p 포인터를 통해 i 값을 읽어옵니다
*p = 21         // p 포인터를 통해 i 값을 설정합니다
 
go
fmt.Println(*p) // p 포인터를 통해 i 값을 읽어옵니다
*p = 21         // p 포인터를 통해 i 값을 설정합니다
 

이것을 "역참조" 또는 "간접 참조"라고 해요.

C언어와 달리 Go 언어는 포인터 연산을 지원하지 않아요.

아래는 포인터를 사용하는 예제 코드예요:

go
package main
 
import "fmt"
 
func main() {
	i, j := 42, 2701
 
	p := &i         // i를 가리키는 포인터
	fmt.Println(*p) // 포인터를 통해 i 값을 읽어옵니다
	*p = 21         // 포인터를 통해 i 값을 변경합니다
	fmt.Println(i)  // i의 새로운 값을 확인해 봅니다
 
	p = &j         // j를 가리키는 포인터
	*p = *p / 37   // 포인터를 통해 j 값을 37로 나눕니다
	fmt.Println(j) // j의 새로운 값을 확인해 봅니다
}
 
go
package main
 
import "fmt"
 
func main() {
	i, j := 42, 2701
 
	p := &i         // i를 가리키는 포인터
	fmt.Println(*p) // 포인터를 통해 i 값을 읽어옵니다
	*p = 21         // 포인터를 통해 i 값을 변경합니다
	fmt.Println(i)  // i의 새로운 값을 확인해 봅니다
 
	p = &j         // j를 가리키는 포인터
	*p = *p / 37   // 포인터를 통해 j 값을 37로 나눕니다
	fmt.Println(j) // j의 새로운 값을 확인해 봅니다
}
 

위 코드를 한 줄씩 자세히 살펴볼게요.

go
i, j := 42, 2701
 
go
i, j := 42, 2701
 
  • ij 변수를 선언하고 각각 42와 2701로 초기화합니다.
go
p := &i         // i를 가리키는 포인터
 
go
p := &i         // i를 가리키는 포인터
 
  • p 변수를 i의 주소로 초기화하는 포인터로 선언합니다.
go
fmt.Println(*p) // 포인터를 통해 i 값을 읽어옵니다
 
go
fmt.Println(*p) // 포인터를 통해 i 값을 읽어옵니다
 
  • p 포인터가 가리키는 값, 즉 i 값을 출력합니다.
go
*p = 21         // 포인터를 통해 i 값을 변경합니다
 
go
*p = 21         // 포인터를 통해 i 값을 변경합니다
 
  • p 포인터가 가리키는 값, 즉 i 값을 21로 변경합니다.
go
fmt.Println(i)  // i의 새로운 값을 확인해 봅니다
 
go
fmt.Println(i)  // i의 새로운 값을 확인해 봅니다
 
  • i 변수의 값을 출력하여 21로 변경되었음을 확인합니다.
go
p = &j         // j를 가리키는 포인터
 
go
p = &j         // j를 가리키는 포인터
 
  • p 포인터를 j의 주소로 변경합니다. 이제 pj를 가리킵니다.
go
*p = *p / 37   // 포인터를 통해 j 값을 37로 나눕니다
 
go
*p = *p / 37   // 포인터를 통해 j 값을 37로 나눕니다
 
  • p 포인터가 가리키는 값, 즉 j 값을 37로 나눕니다.
go
fmt.Println(j) // j의 새로운 값을 확인해 봅니다
 
go
fmt.Println(j) // j의 새로운 값을 확인해 봅니다
 
  • j 변수의 값을 출력하여 73으로 변경되었음을 확인합니다. (2701 / 37 = 73)

위의 예제를 통해 포인터를 선언하고 사용하는 기본적인 방법을 배웠어요. 포인터는 메모리 주소를 저장하고 해당 주소에 저장된 값을 간접적으로 접근할 수 있게 해준답니다.

Go에서는 포인터 연산을 지원하지 않기 때문에 포인터로 배열이나 구조체 요소에 접근할 때는 인덱스나 필드 이름을 사용해야 해요. 예를 들어 *p++와 같은 포인터 연산은 불가능하죠.

포인터는 Go에서 자주 사용되며, 특히 구조체, 함수 매개변수, 리턴 값 등에서 효율적인 메모리 사용을 위해 활용된답니다. 포인터를 잘 이해하고 활용하면 Go 프로그램의 성능을 높일 수 있어요.

YouTube 영상

채널 보기
미들웨어 적용과 라우팅 | NestJS 가이드
NestJS 필터 바인딩 - Method, Controller, Global Scope 비교 | NestJS 가이드
펑터 타입 클래스 | 프로그래머를 위한 카테고리 이론
리더 펑터 - 함수도 펑터다! | 프로그래머를 위한 카테고리 이론
커스텀 예외 필터 만들기 | NestJS 가이드
Maybe 펑터와 타입 들어올리기 | 프로그래머를 위한 카테고리 이론
펑터 합성 | 프로그래머를 위한 카테고리 이론
Const 펑터 - 아무것도 안 하는 펑터가 필요한 이유 | 프로그래머를 위한 카테고리 이론