기본 데이터 형식에 대한 자세한 정보

완료됨

Go는 강력한 형식의 언어입니다. 선언하는 모든 변수는 특정 데이터 형식에 바인딩되며 이 형식과 일치하는 값만 허용합니다.

Go에는 다음과 같은 네 가지 범주의 데이터 형식이 있습니다.

  • 기본 형식: 숫자, 문자열, 부울
  • 집계 형식: 배열, 구조체
  • 참조 형식: 포인터, 조각, 맵, 함수, 채널
  • 인터페이스 형식: 인터페이스

이 모듈에서는 기본 형식만 다룹니다. 다른 형식을 몰라도 걱정할 필요가 없습니다. 이후 모듈에서 다루게 될 것입니다.

숫자 데이터 형식을 살펴보는 것으로 시작해 보겠습니다.

정수

일반적으로 정수 형식을 정의하는 키워드는 int입니다. 그러나 Go는 int8, int16, int32, int64 형식도 제공합니다. 이들은 각각 8, 16, 32 또는 64비트 크기의 정수입니다. 32비트 운영 체제를 사용할 때 int를 사용하면 크기는 일반적으로 32비트입니다. 64비트 시스템에서 int 크기는 일반적으로 64비트입니다. 그러나 이 동작은 컴퓨터마다 다를 수 있습니다. uint을 사용할 수 있습니다. 그러나 특정 이유로 값을 부호 없는 숫자로 표현해야 하는 경우에만 이 형식을 사용합니다. Go는 uint8, uint16, uint32, uint64 형식도 제공합니다.

Go에서 다양한 정수 형식을 사용하는 방법의 예는 다음과 같습니다.

var integer8 int8 = 127
var integer16 int16 = 32767
var integer32 int32 = 2147483647
var integer64 int64 = 9223372036854775807
fmt.Println(integer8, integer16, integer32, integer64)

대부분의 경우 int를 사용하지만 다른 정수 형식에 대해서도 알아야 합니다. Go에서는 정수의 기본 크기가 32비트인 경우에도 intint32와 동일하지 않기 때문입니다. 즉, 캐스트가 필요한 경우 명시적으로 캐스팅해야 합니다. 서로 다른 형식 간에 수학 연산을 수행하려고 하면 오류가 발생합니다. 예를 들어 다음과 같은 코드가 있다고 가정합니다.

var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(integer16 + integer32)

프로그램을 실행하면 다음과 같은 오류가 표시됩니다.

invalid operation: integer16 + integer32 (mismatched types int16 and int32)

보시다시피 Go에서 값을 한 형식에서 다른 형식으로 변환하는 경우 새 형식을 명시적으로 지정해야 합니다. 이 모듈의 끝에서는 형식을 적절하게 캐스팅하는 방법에 대해 설명하겠습니다.

Go 학습을 진행하면서 rune에 대해 들을 수 있습니다. rune은 단순히 int32 데이터 형식에 대한 별칭입니다. 유니코드 문자 또는 유니코드 코드 포인트를 나타내는 데 사용됩니다. 예를 들어 다음과 같은 코드가 있다고 가정하겠습니다.

rune := 'G'
fmt.Println(rune)

이전의 코드 조각을 실행하면 명령 프롬프트에 G가 출력될 것이라고 예상할 수 있습니다. 하지만 G의 유니코드 문자를 나타내는 숫자 71이 표시됩니다. 이후 모듈에서 rune에 대해 자세히 설명하겠습니다.

Go 소스 코드를 살펴보면서 각 형식의 범위에 대해 알아볼 수 있습니다. 각 형식의 범위를 알면 적절한 데이터 형식을 선택하는 데 도움이 되며, 메모리의 비트 낭비도 피할 수 있습니다.

과제 1

int 형식의 다른 변수를 설정하고 integer32 또는 integer64 변수의 값을 사용하여 시스템에 있는 변수의 기본 크기를 확인합니다. 32비트 시스템에서 2,147,483,647보다 큰 값을 사용하는 경우 constant 9223372036854775807 overflows int 같은 오버플로 오류가 발생합니다.

과제 솔루션:

package main

import "fmt"

func main() {
   var integer32 int = 2147483648
   fmt.Println(integer32)
}

과제 2

uint 같은 부호 없는 변수를 선언하고 -10 같은 음수 값으로 초기화합니다. 프로그램을 실행하려고 하면 constant -10 overflows uint 같은 오류 메시지가 표시됩니다.

과제 솔루션:

package main

import "fmt"

func main() {
   var integer uint = -10
   fmt.Println(integer)
}

부동 소수점 숫자

Go는 두 개의 부동 소수점 숫자 크기인 float32float64에 대한 데이터 형식을 제공합니다. 큰 숫자를 저장해야 하고 숫자가 앞에서 언급한 정수 형식에 맞지 않을 때 이 형식을 사용할 수 있습니다. 이 두 형식 간의 차이점은 보유할 수 있는 비트의 최대 크기입니다. 이 두 형식을 사용하는 방법에 대한 자세한 내용은 다음 줄을 참조하세요.

var float32 float32 = 2147483647
var float64 float64 = 9223372036854775807
fmt.Println(float32, float64)

math 패키지에서 사용할 수 있는 math.MaxFloat32math.MaxFloat64 상수를 사용하여 이 두 형식의 제한을 찾을 수 있습니다. 다음 코드를 사용하여 명령 프롬프트에서 최대 부동 소수점 값을 인쇄합니다.

package main

import (
    "fmt"
    "math"
)    

func main() {
    fmt.Println(math.MaxFloat32, math.MaxFloat64)
}

부동 소수점 형식은 10진수를 사용해야 하는 경우에도 유용합니다. 예를 들어 다음과 같은 코드를 작성할 수 있습니다.

const e = 2.71828
const Avogadro = 6.02214129e23
const Planck = 6.62606957e-34

위의 코드를 사용하는 경우 Go는 사용된 값에서 데이터 형식을 유추합니다.

부울

부울 형식에는 두 가지 가능한 값인 truefalse가 있습니다. bool 키워드를 사용하여 부울 형식을 선언합니다. Go는 다른 프로그래밍 언어와 다릅니다. Go에서는 부울 형식을 암시적으로 0이나 1로 변환할 수 없습니다. 명시적으로 이 작업을 수행해야 합니다.

따라서 다음과 같이 부울 변수를 선언할 수 있습니다.

var featureFlag bool = true

이후 모듈에서 Go의 제어 흐름 문에 관해 설명할 때 부울 데이터 형식을 사용할 것입니다. 또한 앞으로 다른 모듈에서도 이를 사용할 것입니다.

문자열

마지막으로, 모든 프로그래밍 언어에서 가장 일반적인 데이터 형식인 문자열을 살펴보겠습니다. Go에서 string 키워드는 문자열 데이터 형식을 나타내는 데 사용됩니다. 문자열 변수를 초기화하려면 큰따옴표(") 내에서 값을 정의해야 합니다. 작은따옴표(')는 단일 문자에(이전 섹션에서 살펴보았듯이 rune에) 사용됩니다.

예를 들어 다음 코드는 문자열 변수를 선언하고 초기화하는 두 가지 방법을 보여 줍니다.

var firstName string = "John"
lastName := "Doe"
fmt.Println(firstName, lastName)

때로는 문자를 이스케이프해야 합니다. 이러한 작업을 수행하려면 문자 앞에 백슬래시(\)를 사용합니다. 예를 들어, 다음은 이스케이프 문자를 사용하는 가장 일반적인 예입니다.

  • \n - 새 줄에
  • \r - 캐리지 리턴에
  • \t - 탭에
  • \' - 작은따옴표에
  • \" - 큰따옴표에
  • \\ - 백슬래시에

다음 코드 조각을 사용하여 이스케이프 문자를 테스트합니다.

fullName := "John Doe \t(alias \"Foo\")\n"
fmt.Println(fullName)

다음 출력이 표시됩니다(새 줄 포함).

John Doe        (alias "Foo")

기본값

지금까지는 변수를 선언할 때마다 값으로 초기화했습니다. 그러나 Go에서는 다른 프로그래밍 언어와 달리 변수를 초기화하지 않을 경우 모든 데이터 형식은 기본값을 갖습니다. 변수를 사용하기 전에 초기화 여부를 확인할 필요가 없기 때문에 이 기능이 유용합니다.

지금까지 살펴본 형식에 대한 몇 가지 기본값 목록은 다음과 같습니다.

  • 0 - int 형식(및 int64와 같은 모든 하위 형식)
  • +0.000000e+000 - float32float64 형식
  • false - bool 형식
  • 빈 값 - string 형식

다음 코드 조각을 실행하여 앞에서 설명한 기본값을 확인하세요.

var defaultInt int
var defaultFloat32 float32
var defaultFloat64 float64
var defaultBool bool
var defaultString string
fmt.Println(defaultInt, defaultFloat32, defaultFloat64, defaultBool, defaultString)

이와 같은 코드를 사용하여 여기에서 탐색하지 않은 데이터 형식의 기본값을 확인할 수 있습니다.

형식 변환

이전 섹션에서는 Go에서 암시적 캐스팅이 작동하지 않음을 확인했습니다. Go에서는 명시적으로 캐스팅을 수행해야 합니다. Go는 한 데이터 형식을 다른 데이터 형식으로 변환하는 몇 가지 기본적인 방법을 제공합니다. 예를 들어 한 가지 방법은 다음과 같이 각 형식에 대해 기본 제공 함수를 사용하는 것입니다.

var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(int32(integer16) + integer32)

Go에서 캐스팅하는 또 다른 방법은 strconv 패키지를 사용하는 것입니다. 예를 들어 stringint로 변환하거나 그 반대로 변환하는 경우 다음 코드를 사용할 수 있습니다.

package main

import (
    "fmt"
    "strconv"
)

func main() {
    i, _ := strconv.Atoi("-42")
    s := strconv.Itoa(-42)
    fmt.Println(i, s)
}

위의 코드를 실행한 후, -42가 두 번 출력되는지 확인합니다.

앞의 코드에서 변수 이름으로 사용된 밑줄(_)이 있습니다. Go에서 _는 해당 변수의 값을 사용하지 않으며 그 값을 무시하겠다는 의미입니다. 이렇게 하지 않으면 선언된 모든 변수를 사용해야 하므로 프로그램이 컴파일되지 않습니다. 이후의 모듈에서 _가 일반적으로 어떤 의미인지는 나중에 이 주제로 돌아와 알아보겠습니다.