Web/GoLang

Golang 구조체 설명

벨포트조던 2021. 7. 28.
반응형

Golang에는 class 개념 대신 struct개념이 있습니다.

쉽게말해 C나 C++에 있는 struct입니다.

 

하지만 Golang에는 다른 OOP와는 다르게, class의 역할중

생성자, 맴버변수 선언을 하지 못합니다.

 

또한 private, public이라는 개념이 따로 없으며,

pirvate과 public이라는 선언대신 해당 struct를 

외부에서 가져다 사용하거나 내부에서 사용할때의 기준을 정할 수 있습니다.

 

선언 방법은 다음과 같습니다.

 

1. 스택에 구조체 선언

package main

import "fmt"

type A struct {
	name string
	num  int
}

func main() {
	a := A{}

	a.name = "hwan"
	a.num = 10
}

위와 같이 선언하면 사용할 수 있습니다.

또한 스택에 할당되면 {hwan 10} 으로 출력이 되지만, 

참조형태 즉, 힙에 할당된 구조체들은 &{hwan 10} 이 출력됩니다.

앞에 &가 붙게됩니다.

 

 

선언과 동시에 초기화도 가능합니다.

package main

import "fmt"

type A struct {
	name string
	num  int
}

func main() {
	a := A{"hwan", 10}
	
	fmt.Println(a) //output : {hwan 10}
}

 

2. new 키워드를 통한 구조체 선언 (힙 할당)

package main

import "fmt"

type A struct {
	name string
	num  int
}

func main() {
	a := new(A)

	a.name = "hwan"
	a.num = 10

	fmt.Println(a) //output : &{hwan 10}
}

 

하지만 new 키워드를 사용해 구조체를 포인터로 받게되면, 선언과 동시에 초기화가 불가능 합니다.

Golang의 구조체는 일반적인 OOP언어에서 볼 수 있는 생성는 따로 없습니다.

또한 출력을 보면 앞에 &가 붙었는데 이는 힙에 할당된 자료로써 참조되고 있다는 뜻입니다.

 

 

때문에 생성자는 사용자가 직접 만들어 줘야합니다.

 

 

3. struct 생성자

package main

import "fmt"

type A struct {
	name string
	num  int
}

func newA() *A {
	a := A{}
	a.name = "hwan"
	a.num = 10

	return &a
}

func main() {
	a := newA()

	fmt.Println(a) //output : &{hwan 10}
}

Golang은 특이하게 주소값을 전달받으면 해당 주소값의 자료들은 모두 스택에서 힙으로 이동하게 됩니다. 이는 클로저 또한 마찬가지 입니다.

 

이를 확인하기위해 golang의 build를 보면 됩니다.

$ go build -gcflags '-m' struct.go 
# command-line-arguments
.\struct.go:10:6: can inline newA
.\struct.go:19:11: inlining call to newA
.\struct.go:21:13: inlining call to fmt.Println
.\struct.go:11:2: moved to heap: a
.\struct.go:19:11: moved to heap: a
.\struct.go:21:13: []interface {}{...} does not escape
<autogenerated>:1: .this does not escape
<autogenerated>:1: .this does not escape

 

a가 heap으로 이동된걸 확인할 수 있습니다.

 

 

4. 함수와 같이 사용

package main

import "fmt"

type A struct {
	name string
	num  int
}

func newA() *A {
	a := A{}
	a.name = "hwan"
	a.num = 10

	return &a
}

func (a *A) print() {
	fmt.Println(a)
}

func main() {
	a := newA()

	a.print() //output : &{hwan 10}
}

golang의 struct에는 맴버함수를 정의하는 기능이 없습니다.

따라서 외부에 함수를 정의하고 struct를 참조하는 형식으로 함수를 만들어야 합니다.

 

print() 함수를 보면 (a * A)라고 struct구조체를 참조하는 형태를 확인할 수 있습니다.

 

 

5. struct의 public & private

public과 private이라고 말하기엔 굉장히 한정적이지만 golang을 사용하는대 있어서 굉장히 중요한 개념입니다.

 

golang에서 struct를 외부에서 가져다 사용하거나 내부에서만 사용하고 싶을 때 기준을 정할 수 있는데,

struct의 이름을 기준으로 정할 수 있습니다.

 

golang은 해당 기준을 변수 이름이 대문자로 시작하냐, 소문자로 시작하냐에 따라 이를 결정짛습니다.

 

대문자로 시작한다면 외부에서 가져다 사용할 수 있고,

소문자로 시작한다면 내부에서만 사용이 가능합니다.

 

 

 

 

반응형

댓글