포인터라는 개(멍멍이)가 있다. 이 개는 사냥감의 위치를 가리키는 일을 한다. 위치 정보를 알려주는 녀석이라고 보면 되겠다.
소프트웨어 개발에서 포인터도 마찬가지다. 소프트웨어의 가장 중요한 일은 데이터를 읽고 쓰는 것인데, 이 데이터들은 메모리에 위치한다. 데이터가 저장된 메모리의 주소를 우리는 메모리 주소라고 하며, 0x123456 과 같은 16진수로 표현한다. 따라서 이론적으로 메모리 주소를 알고 있으면 모든 데이터를 조작 할 수 있다. 하지만 인간이 16진수 값으로 데이터를 조작하기는 쉽지 않으니, 변수로 한단계 추상화해서 사용한다. 0x12345 에 "yundream@example.com"을 저장하라는 것 보다 email에 "yundream@example.com"을 저장하라는게 훨씬 쉽다.
변수에는 값을 저장하는 일반변수와 값이 저장된 데이터의 주소를 저장하는 포인터가 있다. 아래 그림을 보자.
변수 "a"는 int 형 값인 10 이 저장되어 있다. 값이 저장된 메모리 주소는 0x0001 이다.
포인터 "p"는 메모리 주소 0x0001이 저장되어 있다. 0x0001에는 10이 저장되어 있으므로 포인터 p를 이용해서 값을 읽을 수 있다. 메모리 주소에 있는 값의 타입을 알아야 하기 때문에 포인터도 데이터 타입을 가진다.
프로그램의 실행시 동적으로 메모리를 확보하는 영역으로 스택과 힙이 있다. 스택 메모리는 함수 호출 스택을 저장하고 로컬변수, 인수, 반환 값이 저장된다. 따라서 포인터가 아닌 값을 함수의 인수로 하게 되면, 스택에 새로운 메모리공간이 만들어지고 여기에 데이터가 복사된다. 이 데이터는 함수안에서만 유효하다. 코드 실명결과를 보면 메모리 주소가 다른 걸 확인 할 수 있다. 메모리 주소가 다르기 때문에 데이터도 서로 다르다.
이걸 포인터로 변경해보자.
리시버는 값 리시버(Value receiver)과 포인트 리시버(Point receiver)이 있다.
객체지향 언어의 Call by reference와 Call by value와 차이가 없다. 포인터 리시버는 Call by reference 하겠다는 거다. 아래 예제를 보자.
인터페이스(interface)는 Go에서 제공하는 훌륭한 개며이며, 다형성을 구현하는 유일한 방법이기도 하다.
Go 에서 인터페이스는 스트럭처가 구현 해야 하는 메서드 시그니처의 집합이다. 객체지향에 익숙하다면 인터페이스를 구현하기 위해서 implement키워드를 사용했을 것이다. Go 에서는 명시적으로 implement 키워드를 선언하지 않고 구현할 수 있다. 그냥 해당 구조체가 메서드를 구현했다면 implement 한 것으로 간주한다.
개발자는 인터페이스의 메서드를 구현 할 때, 값 리시버와 포인트 리시버를 사용 할 수 있는데 이때 주의해야 할 사항이 있다.
인터페이스의 모든 메서드를 값 리시버로 구현하는 경우 값과 포인터 모두를 사용 할 수 있다.
cannot use (lion literal) (value of type lion) as animal value in assignment: missing method breathe (breathe has pointer receiver)compilerInvalidIfaceAssign
Contents
1. Pointer
2. 선언과 사용
3. 스트럭처와 포인터
4. 포인터와 리시버
5. 인터페이스와 포인터
6. 참고
1. Pointer
2. 선언과 사용
3. 스트럭처와 포인터
4. 포인터와 리시버
5. 인터페이스와 포인터
6. 참고
Recent Posts
Archive Posts
Tags