한 눈에 끝내는 고랭 기초
    • 01
      시작하기에 앞서
    • 강의대상
      Go란?
      실습 환경 구축 - 구름IDE
      Hello goorm! 출력해보기
    • 02
      변수와 상수
    • 콘솔 출력 함수의 기본
      변수의 선언과 초기화
      상수의 선언과 초기화
      간단한 덧셈
      잘못된 신상정보
    • 03
      연산자
    • 연산자 종류
      연산자 우선순위
      콘솔 입력 함수의 기본
      간단한 덧셈과 곱셈
      몫과 나머지
    • 04
      자료형
    • 자료형의 종류와 특징
      문자열의 표현
      자료형의 변환
      강제 형 변환
    • 05
      콘솔 출력과 입력 함수
    • 콘솔 출력 함수(Print)
      콘솔 입력 함수(Scan)
      정돈된 표
      신상정보 입력과 출력
    • 06
      반복문 - for
    • 오로지 for
      구구단
      빛나는 이등변삼각형
    • 07
      조건문 - if/else
    • 조건에 따른 실행과 흐름 분기
      7과 9의 배수
      두 수의 차
    • 08
      분기문 - switch
    • swich문에 의한 선택적 실행
      안좋은 계산기
    • 09
      제어문
    • break, continue, goto문
      구구단2
      두 수를 더하면 99
    • 10
      컬렉션
    • 배열(Array)
      슬라이스(Slice)
      맵(Map)
      역행렬
      가장 긴 이름
      중간고사 평균 점수
    • 11
      함수
    • Go언어에서의 함수
      전역변수와 지역변수
      매개변수
      반환값(리턴값)
      익명 함수
      오름차순 정렬
      아이패드를 사주는 조건
      역학적 에너지
    • 12
      클로저
    • 외부 변수 접근 : 클로저
      동전 정리
    • 13
      구조체와 메소드
    • 구조체
      메소드
      성적 저장 프로그램
      역학적 에너지2
    • 14
      인터페이스(interface)
    • 메소드의 집합 인터페이스
      직육면체와 원기둥
    • 15
      defer와 panic()
    • 지연 처리 defer
      종료하는 panic(), 복구하는 recover()
      엘리베이터
      중간고사 평균 점수2
    • 16
      에러 처리
    • 에러 처리의 기본
      에러 출력 및 처리
      중간고사 평균 점수3
    • 17
      고루틴(Goroutine)
    • 비동기 프로세스의 기본
      고루틴의 활용
      고루틴 실습
    • 18
      채널(Channel)
    • 고루틴의 데이터 통로 : 채널
      비동기 채널과 버퍼
      동기 채널
      채널 닫기
      송신 전용, 수신 전용 채널
      채널 select문
      고루틴 실습2
      메시지 전송
      동기 채널 실습
      비동기 채널 실습
    • 19
      패키지(package)
    • 패키지의 개념
    • 20
      실전 프로젝트 - 마일리지 상점
    • 프로젝트를 시작하기 앞서
      실습모드에서 실습
      마일리지 상점의 주요 기능
      필수 구조체와 매인 메뉴
      잔여 수량, 잔여 포인트 구현
    • 21
      실전 프로젝트 - 주문하기, 장바구니 담기
    • 구매 구현(1)
      구매 구현(2)
      장바구니에 담기
      장바구니 확인(1)
      장바구니 확인(2)
    • 22
      실전 프로젝트 - 고루틴으로 배송하기
    • 배송 상태 확인(1)
      배송 상태 확인(2)
      배송 상태 확인(3)
      최종 코드
    구조체
    13 구조체와 메소드
    구조체

    구조체(Structure)는 프로그래밍에 있어서 없어서는 안 되는 매우 중요한 요소입니다. 구조체는 '하나 이상의 변수를 묶어서 새로운 자료형을 정의하는 Custom data type'입니다. Go언어에서의 구조체는 필드들의 집합체이며 필드들의 컨테이너입니다. C언어와 같은 절차 지향 언어에서 구조체는 객체들의 공통되는 속성과 특징에 따라 쓰입니다. 예를 들어, 사람의 정보를 저장한다고 생각해봅시다. 사람의 정보로는 이름, 성별, 나이, 전화번호, 직업 등등이 있습니다. 그래서 사람을 추가할 때마다 각각의 정보를 선언하고 초기화 하는 것이 아니라 '사람'이라는 구조체 안에 묶어서 저장합니다.  즉, '정보 집합'이라는 것입니다.

    하지만, Go언어는 객체 지향을 따른다고 했습니다. 여기서 주의해야 할 것은 Go언어는 전통적으로 객체 지향 언어의 클래스, 객체, 상속 개념이 없다는 것입니다. 그와 유사한 형태로 따르고 있는 것입니다. Go언어에서 클래스는 Custom 타입을 정의하는 구조체로 표현되는데, 이는 전통적인 객체지향의 클래스가 필드와 메소드를 함께 갖는 것과 달리 구조체는 필드만을 가지고, 메소드는 별도로 분리하여 정의하는 것입니다. 메소드와 관련된 구조체에 대한 설명은 '메소드' 강의에서 다루겠습니다.

    '함수' 챕터에서 익명 함수를 배울 때 함수의 원형을 정의하기 위해 type문을 사용한 적이 있습니다. 구조체도 이와 마찬가지로 Custom data type이기 때문에 type문을 사용해서 구조체를 정의합니다. 아래에 구조체의 선언 형태를 알아보기 위해 사람의 정보를 만들 수 있는 구조체를 만들었습니다.

    go

    그리고 구조체 객체를 생성하는 방법에 대해서 알아보겠습니다. 구조체 선언은 단순히 형태의 선언입니다. "앞으로 person이라는 형은 이렇게 쓸거야."라고 한 것일 뿐, 그 형을 이용해 아무것도 만들지 않으면 아무 의미가 없습니다. 따라서 구조체는 선언 후 객체를 생성해서 사용할 수 있습니다. 

    구조체 객체 선언은 지난 강의에서 배운 '컬렉션 - 슬라이스, 맵'과 선언 방식이 유사합니다. 우선 특징에 대해 알아보겠습니다.

    구조체 객체를 생성하려면 "객체이름 := 구조체이름{저장할값}"으로 입력해 선언과 동시에 초기화를 할 수 있습니다. 만약에 저장할값에 아무것도 입력하지 않는다면 빈 객체가 생성됩니다. 만약 빈 객체로 생성했다면 "객체이름.필드이름 = 저장할값"으로 저장할 수 있습니다. '.(dot)'을 이용하면 필드 값을 저장하는 기능만 있는 것이 아니라 필드 값을 접근할 수 있는 용법입니다. 그리고 빈 객체 혹은 만약 일부 필드가 생략될 경우 생략된 필드들은 Zero value (정수인 경우 0, float인 경우 0.0, string인 경우 "", 포인터인 경우 nil 등)를 갖습니다. 이 용법에 대해 아래 간단한 코드로 확인해보겠습니다.

    아래 코드를 바로 실행해보세요.

    go
    실행 결과를 확인해보세요!

    위 코드에서 눈여겨 봐야 할 것은 선언과 동시에 초기화 할 때 두 가지 방법이 있다는 것입니다. 초기화 할 때 값을 나열하면 구조체에 선언한 필드 순서대로 저장됩니다. 하지만 필드 이름에 값을 지정한다면 순서에 상관없이 해당 필드에 값이 저장됩니다. 그리고 Go언어의 구조체는 기본적으로 'mutable' 개체로서 필드 값이 변화할 경우 별도로 새 개체를 만들지 않고 해당 개체 메모리에서 직접 변경됩니다. 위 코드에서 p3.name = "ryu"를 입력해 값을 직접 수정했습니다.

    그리고 함수(메소드)에서 같이 값을 복사해서 지역 변수로 사용하는 경우가 아니라 원래 값의 주소를 참조해 값이 저장된 주소에 직접 접근 하는 경우에 포인터를 썼습니다. 매개변수에 '&'을 붙여서 Pass by reference를 한 것입니다. 구조체도 마찬가지로 '구조체 포인터'를 생성할 수 있습니다. 구조체 포인터를 생성하는 방법은 두 가지가 있습니다.

    1. 'new(구조체이름)'을 사용하여 객체를 생성하기.
    2. 구조체 이름 앞에 & 붙이기.

    주의할 점은, 다른 자료형의 포인터들은 역참조를 위해 '*' 연산자를 사용했습니다. 하지만 포인터 구조체는 선언하면 자동으로 역참조 됩니다. 따라서 함수 안에서 * 연산자를 사용할 필요가 없습니다.


    아래 구조체 포인터를 만드는 간단한 예시가 있습니다. 바로 실행해보세요.

    go
    실행 결과를 확인해보세요!

    생성자(constructor) 함수


    구조체는 사용자 임의로 하나 이상의 변수를 묶어 새로운 자료형을 정의한 것이라고 했습니다. 이때, 구조체를 사용하기 위해서는 우선 객체를 생성해야 사용할 수 있습니다. 그런데 때로는 구조체의 필드 자체가 사용 전에 초기화되어야 하는 경우가 있습니다. 예를 들어, 구조체의 필드가 'map' 형일 경우 구조체를 초기화할 때마다 맵 필드도 같이 초기화해야 하는 번거로움이 있을 수 있습니다. 따라서 사전에 미리 초기화를 해 놓으면 외부 구조체 사용자가 매번 맵을 초기화해야 한다는 것을 기억할 필요가 없습니다.

    이러한 목적을 위해 '생성자 함수'를 사용할 수 있습니다. 생성자 함수는 호출하면 구조체 객체 생성 및 초기화, 입력한 필드 생성 및 초기화함과 동시에 구조체를 반환합니다.  

    go

    위 생성자 함수는 구조체 객체를 포인터와 함께 반환합니다. 포인터 값이 없는 객체를 생성하는 생성자를 만들려면 반환형에 구조체 이름 앞에 붙은 포인터 연산자를 없애면 됩니다.


    위 생성자 함수를 이용해 구조체를 만드는 아래 예시 코드를 실행해보세요.

    go
    실행 결과를 확인해보세요!

    위 예시에서 s1 객체는 생성자 함수로 data 필드의 맵을 초기화했기 때문에 바로 data 필드에 값을 저장할 수 있습니다. 하지만 s2 객체는 구조체만 생성했기 때문에 data 필드에 값을 저장하기 위해 선언이 필요한 맵은 따로 초기화해야 합니다.

    이렇게 생성자 함수를 사용하면 구조체의 사용이 훨씬 수월해질 수 있습니다. 형태를 익히기 바랍니다.

    질문하기