티스토리 뷰

Programming Language/Go

[Go] 구조체

SdardewValley 2021. 11. 20. 23:00
반응형

구조체

속성을 가진 실제 엔티티를 표현한 것이다 이름과 필드를 사용하여 속성들을 표현할 수 있다.

 

구조체 정의

type 타입명1 struct {
    필드명1 필드타입1
    필드명2 필드타입2
    ...
}

type 타입명2 struct {
    필드명1-1, 필드명1-2 필드타입1
    필드명2 필드타입2
    ...
}

type 타입명3 struct { 필드명1, 필드명2 필드타입 }

내장 데이터 타입과 더불어 인터페이스, 함수 signature, 다른 구조체도 필드로 지정 가능하다.

 

필드 타입이 동일하면 묶어서 타입명2처럼 타입을 지정할 수 있다.

 

모든 필드의 타입이 동일하면 타입명3처럼 한 줄로 필드들을 표기할 수 있다.

 

 

생성 & 초기화

타입 {초기값} // 1. 구조체 리터럴
&타입 {초깃값} // 2. 구조체 리터럴의 포인터
new(타입) // 3. 구조체 포인터

 

1. 구조체 리터럴

 

필드와 값을 나열해서 생성하는 방식이다. 필드에 값을 입력하지 않았다면, 0값으로 초기화된다. 필드명을 지정하지 않았다면, 필드 순서대로 값이 할당된다.

 

구조체 정의
구조체 생성
출력한 구조체 내용

shoes 구조체는 순서대로 값을 표기하여 생성하였다. dress를 보면 quantity 값을 설정해 주지 않아 quantity 값은 0이 출력된다.

 

2. 구조체 리터럴의 포인터

구조체 포인터 생성
구조체 정보 출력

구조체 리터럴 앞에 주소 연산자 &를 붙여서 포인터를 생성하면 된다.

 

포인터를 통해서 메서드를 호출할 수 있다.

 

3. new() 함수

new 함수는 제로값을 초기화된 구조체를 생성하고, 포인터를 반환한다.

 

생성한 포인터를 통해서 필드값을 채우면 된다.

 

익명 구조체

구조체를 타입으로 정의하지 않고 익명으로 사용하는 것이다.

 

rects를 보면 struct가 정의되지 않고 익명으로 사용되는 것을 확인할 수 있다.

 

 

내부 필드 접근

내부 필드에는 . 연산자를 사용하여 접근한다.

 

내부필드로 Size를 사용
선언한 모습

Size 처럼 내부 필드로 struct로 사용이 가능하다. 

 

%#v를 사용한 모습
출력 결과

Pintf에서 %#v를 사용하여 구조체를 출력하면 값이 필드명과 함게 출력된다.

 

 

태그

태그를 추가

구조체 필드에 옵션으로 추가되는 문자열로 필드에 대한 설명을 추가할 때 사용한다. 위의 코드에서는 "이름", "가격", "수량", "사이즈"가 태그이다.

 

태그를 출력하는 모습
출력 결과

태그는 relect.TypeOf() 함수를 사용하여 확인할 수 있다.

 

 

구조체 임베딩

type 타입명 struct {
	타입1 // 임베디드 필드
    타입2 // 임베디드 필드
    ...
}

type 타입1 struct {
	...
}

type 타입2 struct {
	...
}

사용자 정의 타입을 구조체의 필드로 지정하는 것을 임베딩이라고 한다.go에서는 상속을 사용하지 않고 사용자 정의 타입을 조합하여 구조체를 정의하는 방식으로 객체를 재사용한다.

 

이렇게 조합을 사용하면 상속에서 부모-자식 관계가 생기고, 프로그램의 규모가 커져 상속 관계가 깊어지면 발생하는 문제를 해결할 수 있다.

 

임베디드 필드를 사용한 모습

 

 

임베디드 필드

내부 필드에 접근하는 것과 마찬가지로 임베디드에 필드에 접근할 때도 .을 사용하면 된다.

 

같은 이름의 필드에 접근할 때는 임베디드 필드의 타입(struct의 식별자)를 함께 사용하면 된다.

 

메서드 재사용

 

구조체 임베드를 사용하면 포함되어 있는 임베디드 필드에 관한 메서드를 재사용할 수 있다.

메서드를 재사용하는 모습

DiscountItem을 보면 Item를 임베디드 필드로 가지고 있다. 따라서 Item 필드 관련된 함수 Cost를 DiscountItem에서도 사용할 수 있다.

 

메서드 오버라이딩

 

오버라이딩은 단순히 말하면 재정의이다. DiscountItem은 할인된 제품인데 Cost 함수를 그대로 적용하기 보다는 이를 오버라이딩하는 것이 좋을 것이다.

 

위와 같이 Cost 함수를 오버라이딩하였다.

 

참고로, Goland에서 코드를 복제할 때 복제할 부분을 지정하고 ⌘(command) + D 키를 누르면 복제된다.

 

💡 오버로딩

Go에서는 오버로딩이 지원되지 않는다. 따라서, 다른 이름의 함수를 정의하거나 혹은 매개변수에 ... 부호를 사용하여 오버로딩 효과를 줄 수 있다.

 

정보 은닉

식별자의 첫 글자가 대문자이면 public, 소문자이면 private으로 구분되는 것처럼, 구조체의 필드도 대문자로 시작하는 필드(exported field)이면 외부에서 접근이 가능하고 소문자로 시작하는 필드(non-exported field)이면 패키지 내부에서만 접근이 가능하다.

 

Go에서는 이런 소문자로 시작하는 필드로 정보 은닉을 할 수 있다.

 

생성자

Go의 구조체는 생성자를 지원하지 않지만, 생성 함수를 사용하여 생성자와 같은 효과를 낼 수 있다.

 

💡 생성 함수 Convention

생성 함수의 이름은 New + 구조체 이름으로 지정한다. 패키지명과 타입명이 같다면 생성 함수 이름은 New(...)로 한다.

 

getter & setter

Item의 name 필드에 대한 getter과 setter이다.

 

💡 getter & setter Convention

getter은 get으로 시작할 필요 없이 필드명과 같은 이름으로 짓고 대문자로 시작한다. setter는 Set +필드명으로 작성한다.

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함