[GoLang] 구조체

Pyo·2023년 11월 3일
0


이 글은 Tucker의 Go언어 프로그래밍 책을 13장 구조체를 보고 정리한내용이다.

구조체

구조체는 여러 필드를 묶어서 사용하는 타입이다. 구조체를 사용하면 연관된 여러 데이터를 하나의 이름으로 묶을수 있다.

선언 및 기본 사용

type Home struct{
	Address string
    Size int
    Price float64
    Type string
}

구조체 변수 초기화

  • 초기값 생략
var house House

모든 필드가 기본값으로 초기화된다.

  • 모든 필드 초기화
var house House = House {"서울시 서초구",8,0.6,"오피스텔"}

모든 필드가 순서대로 초기화된다.

  • 일부 필드 초기화
var house House = House {Size:28 , Type:"오피스텔"}

'필드명':'필드값' 형식으로 초기화 되며 , 초기화 되지 않은 나머지 변수에는 기본값 할당

구조체를 포함하는 구조체

  • 내장 타입처럼 포함하는 방법
type User struct {
	Name string
	ID   string
	Age  int
}

type VIPUser struct {
	UserInfo User
	VIPLevel int
	Price    int
}

VIPUser 구조체에서 User 구조체 안의 변수로 접근하려면 VIPUser.User. 으로 접근해야하는 번거로움이 있다.

  • 포함된 필드 방식
type User struct {
	Name string
	ID   string
	Age  int
}

type VIPUser struct {
	User
	VIPLevel int
	Price    int
}

VIPUser 구조체에서 User 구조체의 필드명을 생략하게 되면 User 구조체 변수 접근시 VIPUser. 로 바로 접근할수 있다.

  • 필드 중복 해결
type User struct {
	Name  string
	ID    string
	Age   int
	Level int
}

type VIPUser struct {
	User
	Price int
	Level int
}

VIPUser 구조체의 변수와 User 구조체 변수가 같을 때 User 구조체 변수를 접근하려면 VIPUser.User. 으로 접근하면 된다.

구조체 크기

type User struct{
	Age int
	Score float64
}

int(8바이트) + float64(8바이트) = 16바이트

  • 구조체 값 복사 : 구조체 변숫값을 다른 구조체에 대입하면 모든 필드값이 복사된다.
  • 필드 배치 순서에 따른 구조체 크기 변화
package main

import (
	"fmt"
	"unsafe"
)

type User struct {
	Age   int32	// 4바이트
	Score float64 // 8바이트
}

func main() {
	user := User{23, 77.2}

	fmt.Println(unsafe.Sizeof(user))	// 16
}

배운대로 라면 12바이트 출력되어야 한다. 16바이트가 출력되는 이유는 ??

  • 메모리 정렬 : 컴퓨터가 효과적으로 접근하고자 메모리를 일정 크기 간격으로 정렬하는것이다. 64비트 컴퓨터에서는 8바이트 단위로 정렬되는 것이 효과적이므로 12바이트가 아닌 4바이트 메모리 패딩을 통해 크기는 16바이트가 된다.

  • 메모리 패딩을 고려한 필드 배치 방법

package main

import (
	"fmt"
	"unsafe"
)

type User struct {
	A int8
	B int	// int64
	C int8
	D int	// int64 
	E int8
}

func main() {
	user := User{1, 2, 3, 4, 5}
	fmt.Println(unsafe.Sizeof(user))	//40
}

실제 1바이트 3개와 8바이트 2개로 구성되어 있기 때문에 19바이트 크기를 차지한다. 하지만 1바이트 변수는 7바이트씩 메모리 패딩으로 인해 크기는 ((1+7) 3) + (8 2) 40이 된다.

package main

import (
	"fmt"
	"unsafe"
)

type User struct {
	A int8
	B int8
	C int8
	D int
	E int
}

func main() {

	var user = User{1, 2, 3, 4, 5}

	fmt.Println(unsafe.Sizeof(user)) // 24

}

이렇게 1바이트를 몰아 주면 구조체의 크기를 8바이트 * 3 = 24 로 순서 조정 전보다 16바이트를 절약할수 있다.

프로그래밍에서 구조체 역할

함수,배열,구조체 모드 응집도를 증가시키는 역할을 한다. 구조체를 사용해서 관련 데이터들을 묶으면 개별 데이터에 집중하지 않고 큰 범위에서 생각할 수 있게 되었다.

정리

  • 구조체는 여러 필드들을 묶은 타입이다.
  • 포함된 필드를 사용하려면 점하나로 접근 가능하다.
  • 메모리 정렬을 위해서 필드간 간격을 띄우는 것을 패딩이라고 한다.
  • 불필요한 메모리 낭비를 줄이려면 작은 크기 필드값을 앞에 배치한다.
  • 구조체에 메서드 , 인터페이슥 추가되면서 객체지향 프로그래밍으로 발전했다.

참고

https://www.youtube.com/@TuckerProgramming

0개의 댓글