🔥 포인터

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 영상

채널 보기
미들웨어 vs 가드, 왜 NestJS에서는 가드가 더 똑똑할까? | NestJS 가이드
Writer 펑터와 클라이슬리 카테고리 | 프로그래머를 위한 카테고리 이론
NestJS 인터셉터란? | NestJS 가이드
변환 파이프로 컨트롤러 코드 깔끔하게 만들기 | NestJS 가이드
함수 객체의 보편적 구성 | 프로그래머를 위한 카테고리 이론
API 응답 지연과 복잡한 에러, NestJS 인터셉터로 관리하는 방법 | NestJS 가이드
C++ 속의 펑터 | 프로그래머를 위한 카테고리 이론
NestJS 인터셉터에서 map 연산자로 응답을 변환하는 방법 | NestJS 가이드