Golang 구조체 (Structures) 완전 정복

GolangBeginner
지금 연습하기

소개

구조체 (structure, struct) 는 서로 다른 유형의 데이터를 저장하는 데 사용될 수 있는 복합 타입입니다. 더 복잡한 데이터 구조를 구현하는 데 사용할 수 있습니다. 예를 들어, 편의점의 상품은 상품명, 카테고리, 가격과 같은 속성을 가지고 있습니다. 우리는 구조체를 사용하여 이를 나타낼 수 있습니다.

이 Lab 에서는 구조체를 정의하고 사용하는 방법에 대해 배우겠습니다.

지식 포인트:

  • 구조체의 정의
  • 구조체 인스턴스의 메서드

구조체 정의

typestruct 키워드를 사용하여 구조체를 정의할 수 있습니다. 구문은 다음과 같습니다.

type StructName struct {
    FieldName Type
    // ...
}

여기서:

  • Type은 필드 이름의 특정 타입을 나타내며, 정수, 문자열 등이 될 수 있습니다.
  • StructName은 동일한 패키지 내에서 고유해야 합니다.
  • 필드 이름은 동일한 구조체 내에서 고유해야 합니다.

한번 시도해 봅시다. 편의점을 정의해 보겠습니다.

type Store struct {
    ProductType string // 상품 유형
    ProductName string // 상품 이름
    Price       int    // 상품 가격
}

위 코드에서, 우리는 편의점을 위한 Store라는 구조체를 정의했으며, 여기에는 상품의 유형, 이름 및 가격이 포함됩니다.

상품 유형과 상품 이름 필드가 동일한 유형이므로, 코드를 다음과 같이 단순화할 수 있습니다.

type Store struct {
    ProductName, ProductType string
    Price                   int
}

var 키워드를 사용한 인스턴스화

이전 섹션에서, 우리는 메모리 공간을 설명하는 편의점 구조체 Store를 정의했습니다. 인스턴스화 후에만 메모리가 할당되고 구조체의 필드를 사용하게 됩니다.

var 키워드를 사용하여 구조체를 인스턴스화할 수 있습니다.

var InstanceName Structure

인스턴스화의 예시를 살펴보겠습니다. struct.go라는 파일을 생성하고 다음 코드를 작성합니다.

cd ~/project
touch struct.go
package main

import "fmt"

type Store struct {
    productName string
    productType string
    price       int
}

func main() {
    // `var` 를 사용하여 구조체 인스턴스화
    var store1 Store
    // 인스턴스 store1 과 관련된 필드에 값 할당
    store1.productType = "Drinks"
    store1.productName = "Coca-Cola"
    store1.price = 3

    fmt.Printf("store1:\n\t%s\n\t%s\n\t%d\n",
        store1.productType, store1.productName, store1.price)
}

프로그램을 실행합니다.

go run struct.go

실행 후, 다음과 같은 결과가 표시됩니다.

store1:
Drinks
Coca-Cola
3

이 프로그램에서, 우리는 var를 사용하여 편의점을 인스턴스화한 다음, . 연산자를 사용하여 해당 필드에 값을 할당했습니다.

구조체의 초기값

값을 할당하지 않고 초기화만 하는 경우, 인스턴스화된 구조체의 값은 어떻게 될까요? 다음 코드를 살펴보겠습니다.

package main

import "fmt"

type Store struct {
    ProductName string
    ProductType string
    Price       int
}

func main() {
    // `var` 를 사용하여 구조체 인스턴스화
    var lan1 Store
    // %#v 를 사용하여 구조체 값 출력
    fmt.Printf("lan1: %#v\n", lan1)
}

프로그램을 실행합니다.

go run struct.go

결과는 다음과 같습니다.

lan1: main.Store{ProductName:"", ProductType:"", Price:0}

초기 값이 지정되지 않은 경우, 인스턴스화된 구조체의 값은 해당 타입의 제로 값 (zero value) 임을 알 수 있습니다. 예를 들어, 문자열은 비어 있고, 정수는 0 입니다.

new 키워드를 사용한 인스턴스화

var 키워드를 사용하여 인스턴스화하는 것 외에도, new 키워드를 사용할 수도 있습니다.

package main

import "fmt"

type Store struct {
    productName string
    productType string
    price       int
}

func main() {
    store := new(Store)
    // %T를 사용하여 타입 출력
    fmt.Printf("Type of store: %T\n", store)

    store.productType = "Daily Necessities"
    store.productName = "Umbrella"
    store.price = 20

    fmt.Printf("store:\n\t%s\n\t%s\n\t%d\n",
        store.productType, store.productName, store.price)
}

프로그램을 실행합니다.

go run struct.go

결과는 다음과 같습니다.

Type of store: *main.Store
store:
        Daily Necessities
        Umbrella
        20

new 키워드를 사용하여 인스턴스화할 때, 생성되는 "인스턴스"는 실제로 인스턴스에 대한 포인터입니다. 구조체 포인터에 값을 할당하는 작업은 일반 구조체에 값을 할당하는 것과 동일합니다.

:= 연산자를 사용한 인스턴스화

마찬가지로, :=를 사용하여 구조체를 인스턴스화할 수 있습니다.

package main

import "fmt"

type Store struct {
    productName string
    productType string
    price       int
}

func main() {
    lan3 := Store{}
    lan3.productType = "Fresh Food"
    lan3.productName = "Taiwanese Meatballs"
    lan3.price = 20
    fmt.Printf("lan3:\n\t%s\n\t%s\n\t%d\n",
        lan3.productType, lan3.productName, lan3.price)
}

프로그램을 실행합니다.

go run struct.go

결과는 다음과 같습니다.

lan3:
    Fresh Food
    Taiwanese Meatballs
    20

**초기화 (initialization)**와 **할당 (assignment)**을 함께 작성할 수 있습니다. 다음과 같이 말이죠.

package main

import "fmt"

type Store struct {
    productName string
    productType string
    price       int
}

func main() {
    lan3 := Store{
        productType: "Fresh Food",
        productName: "Taiwanese Meatballs",
        price:       4,
    }
    fmt.Printf("lan3:\n\t%s\n\t%s\n\t%d\n",
        lan3.productType, lan3.productName, lan3.price)
}

프로그램을 실행합니다.

go run struct.go

결과는 다음과 같습니다.

lan3:
    Fresh Food
    Taiwanese Meatballs
    4

구조체의 모든 필드에 값을 할당해야 하는 경우, 구조체에 정의된 순서대로 값을 작성할 수 있습니다.

예를 들어, lan3 인스턴스를 다음과 같이 다시 작성합니다.

lan3 := Store{
        "Fresh Food",
        "Taiwanese Meatballs",
        4,
    }

참고: 이 구문은 모든 필드에 값을 할당하는 경우에만 적합합니다.

요약

이 랩에서는 구조체 (structure) 를 소개하고 다음 지식 포인트를 요약했습니다.

  • 구조체는 여러 개의 서로 다른 데이터 타입을 포함할 수 있는 복합 데이터 타입입니다.
  • 초기화되지 않은 구조체의 값은 해당 타입의 제로 값 (zero value) 입니다.
  • 구조체를 인스턴스화하는 세 가지 방법.