Featured image of post Golang: 7. 구조체

Golang: 7. 구조체

Go 언어는 객체지향 프로그래밍을 고유의 방식으로 지원한다.

  • 클래스, 객체, 상속 개념이 없다.

전통적인 OOP의 클래스는 Go 언어에서 Custom Type을 정의하는 struct(구조체)로 표현한다.

Struct

Go에서 struct는 Custom Data Type을 표현하는데 사용된다(C 처럼)

  • 필드들의 집합체이며 필드들의 컨테이너이다.
  • struct는 필드 데이터만을 가지며(자료 구조 역할), 메서드는 표현하지 않는다.

메서드는 별도로 분리하여 정의한다.

Struct 선언

구조체를 정의하기 위해서 Custom Type을 정의하는데 사용하는 type 문을 사용한다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package main
 
import "fmt"
 
// struct 정의
type person struct {
    name string
    age  int
}
 
func main() {
    // person 객체 생성
    p := person{}
     
    // 필드값 설정
    p.name = "Lee"
    p.age = 10
     
    fmt.Println(p)
}

person 구조체를 패키지 외부에서 사용할 수 있게 하려면 struct명을 Person으로 변경하면 된다.

struct 객체 생성

선언된 struct 타입으로부터 객체를 생성하는 방법은 몇 가지 방법들이 있다.

  1. 빈 객체를 먼저 할당하고, 나중에 그 필드값을 채워넣는 방법

    1
    2
    3
    4
    
    p := person{}
    
    p.name = "Lee"
    p.age = 10
    
  2. 초기값을 함께 할당하는 방법

    1
    2
    3
    
    var p1 person 
    p1 = person{"Bob", 20}
    p2 := person{name: "Sean", age: 50}
    

    초기화가 생략된 필드들은 Zero value (정수인 경우 0, float인 경우 0.0, string인 경우 “”, 포인터인 경우 nil 등)를 갖는다.

  3. new 내장함수 사용

    1
    2
    
    p := new(person)
    p.name = "Lee"  // p가 포인터라도 . 을 사용한다
    

    new()를 사용하면 모든 필드를 Zero value로 초기화하고 person 객체의 포인터를 반환한다.

    객체 포인터인 경우에도 필드 엑세스시 . 을 사용하는데 이 때 포인터는 자동으로 역참조된다. (c에서 → 과 동일한 동작)

    Go에서 struct는 기본적으로 mutable 개체로서 필드값이 변화할 경우 해당 개체 메모리에서 직접 변경된다. 하지만 struct 개체를 다른 함수의 파라미터로 넘기면, Pass by Value에 따라 객체를 복사해서 전달한다. 따라서 struct 개체의 값을 변경하려면 포인터를 전달해야 한다.

생성자 함수

구조체 필드가 사용 전에 초기화되어야 하는 경우가 있다. 예를 들어 struct 필드가 map 타입인 경우 구조체 할당 후 map을 다시 할당받고 초기화 해야한다.

이럴 때 map을 사전에 미리 초기화 하면, 외부에서 구조체를 사용할 때 별도로 초기화하는 번거로움을 줄일 수 있다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package main
    
type dict struct {
    data map[int]string
}
    
//생성자 함수 정의
func newDict() *dict {
    d := dict{}
    d.data = map[int]string{}
    return &d //포인터 전달
}
    
func main() {
    dic := newDict() // 생성자 호출
    dic.data[1] = "A"
}

생성자 함수인 newDict()dict라는 구조체의 map 필드를 초기화한 후 구조체 포인터를 반호나한다. main 함수에서 구조체 개체를 만들 때 dict를 직접 생성하지 않고 대신 생성자 함수를 통해 이미 초기환 된 data 맵 필드를 사용할 수 있다.