구조

구조체 에서 Go

1개의 연습 문제

구조체 소개

Go에서 struct는 _필드_라고 부르는 이름 있는 요소들의 나열이고, 각 필드는 이름과 타입을 가져요. 필드 이름은 struct 안에서 유일해야 해요. struct는 객체 지향 프로그래밍 패러다임의 _클래스_에 비유할 수 있어요.

struct 정의하기

type과 struct 키워드를 사용하면 새 struct를 만들 수 있고, 필드의 이름과 타입을 명시적으로 정의해요. 예를 들어 여기에서는 도형의 이름과 크기를 담는 Shape struct를 정의해요.

type Shape struct {
    name string
    size int
}

struct의 필드 이름은 Go 관례를 따라요. 이름이 소문자로 시작하는 필드는 같은 패키지의 코드에서만 볼 수 있고, 대문자로 시작하는 필드는 다른 패키지에서도 볼 수 있어요.

struct 인스턴스 만들기

struct를 정의했다면, 이제 필드 이름을 사용해 순서에 상관없이 필드를 지정하면서 새 인스턴스를 만들어요.

s := Shape {
    name: "Square",
    size: 25,
}

인스턴스의 필드를 읽거나 수정하려면 . 표기를 사용해요.

// Update the name and the size
s.name = "Circle"
s.size = 35
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: Circle size: 35

초깃값을 지정하지 않은 필드는 제로 값을 가져요. 예를 들어:

s := Shape{name: "Circle"}
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: Circle size: 0

필드를 순서대로 정의하기만 하면 필드 이름을 사용하지 않고도 struct의 인스턴스를 만들 수 있어요.

s := Shape {
	"Oval",
	20,
}

그런데 이런 문법은 _깨지기 쉬운 코드_로 여겨져요. 필드가 추가될 때, 특히 새 필드의 타입이 다를 때 깨질 수 있거든요. 다음 예제에서는 Shape에 필드를 하나 더 추가해요.

type Shape struct {
	name        string
	description string // new field 'description' added
	size        int
}

s := Shape{
    "Circle",
    20,
}
// Since the second field of the struct is now a string and not an int,
// the compiler will throw an error when compiling the program:
// Output: cannot use 20 (type untyped int) as type string in field value
// Output: too few values in Shape{...}

"New" 함수

때로는 struct 인스턴스를 만드는 데 도움을 주는 함수가 있으면 좋아요. 관례적으로 이런 함수는 보통 New라고 부르거나 이름이 New로 시작해요. 하지만 그냥 일반 함수일 뿐이라 원하는 이름을 아무거나 붙여도 돼요. 다른 언어의 생성자가 떠오를 수도 있지만, Go에서는 그냥 일반 함수예요.

다음 예제에서는 이런 New 함수 중 하나로 Shape의 새 인스턴스를 만들면서 도형의 size에 기본값을 자동으로 설정해요.

func NewShape(name string) Shape {
	return Shape{
		name: name,
		size: 100, //default-value for size is 100
	}
}

NewShape("Triangle")
// => Shape { name: "Triangle", size: 100 }

New 함수를 사용하면 다음과 같은 장점이 있어요.

  • 주어진 값의 유효성 검사
  • 기본값 처리
  • New 함수는 초기화하려는 struct와 같은 패키지에 선언되는 경우가 많아서, struct의 비공개 필드까지 초기화할 수 있어요

이 타입을 더 자세히 알아보려면 다음 자료를 확인해 봐요: Go by Example: Structs, A Tour of Go: Structs 또는 Structures in Go (structs)

new 내장 함수

struct의 새 인스턴스를 만드는 또 다른 방법은 new 내장 함수를 사용하는 거예요.

s := new(Shape) // s will be of type *Shape (pointer to shape)
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name:  size: 0

이 예제에서 new는 struct Shape의 인스턴스를 만들면서 모든 값을 각 타입의 제로 값으로 초기화하고, 그 인스턴스에 대한 포인터를 반환해요.

Note

대부분의 경우 struct의 새 인스턴스를 new 내장 함수로 만드는 것은 보기 어려워요. 항상 struct 리터럴이나 직접 만든 New 함수, 또는 struct를 만드는 데 도움이 되는 패키지에서 제공하는 다른 함수를 우선 사용해요. struct의 새 인스턴스를 만들 때 new 내장 함수는 마지막 수단으로만 사용해요.

GitHub에서 편집 링크가 새 창이나 탭에서 열려요

구조체 배우기