Menu

Golang int를 string으로, string을 int로: 타입 변환

Go에서 타입을 변환하는 방법: strconv로 int를 string으로, string을 int로 바꾸기, 실수를 정수로, T(v)로 하는 숫자 변환, 바이트와 룬, string(65) 함정, 변환 오류 처리를 다룹니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

Go는 절대 암묵적으로 타입을 변환하지 않습니다. 호환되는 타입 사이는 T(v)로, 숫자와 텍스트 사이는 strconv 패키지로 변환합니다. 가장 많이 검색되는 두 가지 변환입니다:

strconv.Itoa("integer to ASCII")는 int를 10진수 텍스트로 형식화합니다. strconv.Atoi("ASCII to integer")는 텍스트를 int로 파싱하고, 텍스트가 올바른 숫자가 아니면 오류를 반환합니다. 그 오류는 항상 확인하세요.

T(v) 변환

Go의 변환 문법은 대상 타입의 이름을 딴 함수 호출처럼 보입니다. 세 가지 상황에서 동작합니다:

  1. 숫자 타입 사이(int, int64, float64, uint8, ...),
  2. string[]byte 또는 []rune 사이,
  3. 기반 타입이 같은 타입 사이(Celsiusfloat64).

결과를 자세히 보세요:

  • int(3.9)3이고 int(-3.9)-3입니다. 변환은 반올림하지 않고 0 쪽으로 절삭합니다. 원하는 동작을 고르려면 먼저 math.Round, math.Floor, math.Ceil을 쓰세요. math.Round는 0.5를 0에서 먼 쪽으로 반올림하므로 -3.5-4가 됩니다.
  • 하위 8비트만 남으므로(300에서 256을 뺌) uint8(300)44이고, 같은 이유로 int8(200)-56입니다. 오류도 패닉도 없습니다.
  • Celsiusfloat64는 기반 타입이 같으므로 자유롭게 변환되지만, 명시적으로만 가능합니다.

값을 일부러 변수에 넣었습니다. 상수라면 같은 변환이 컴파일되지 않습니다.

상수는 검사되고, 변수는 검사되지 않는다

범위에 맞지 않는 상수를 변환하면 컴파일 오류입니다. 같은 값을 가진 변수를 변환하면 조용히 순환합니다:

fmt.Println(uint8(300)) // compile error
x := 300
fmt.Println(uint8(x)) // 44
./main.go:6:20: constant 300 overflows uint8

정수가 아닌 상수를 정수 타입으로 변환하는 것도 거부되지만, 변수에 담긴 같은 값은 절삭됩니다:

./main.go:7:18: cannot convert -3.9 (untyped float constant) to type int

실수 값이 대상 정수 타입의 범위를 벗어나면(예: int64(1e20)) 결과는 구현에 따라 다릅니다. 예를 들어 amd64와 arm64는 다른 답을 줍니다. 신뢰할 수 없는 값은 변환하기 전에 범위를 확인하세요.

숫자를 문자열로 바꾸기

원래 타입함수예시결과
intstrconv.Itoa(n)strconv.Itoa(-7)"-7"
int64strconv.FormatInt(n, base)strconv.FormatInt(255, 16)"ff"
uint64strconv.FormatUint(n, base)strconv.FormatUint(5, 2)"101"
float64strconv.FormatFloat(f, fmt, prec, 64)strconv.FormatFloat(3.14159, 'f', 2, 64)"3.14"
boolstrconv.FormatBool(b)strconv.FormatBool(true)"true"
무엇이든fmt.Sprint(v)fmt.Sprint(3.5)"3.5"
무엇이든, 형식 지정fmt.Sprintf(format, v)fmt.Sprintf("%05d", 42)"00042"

FormatFloat는 형식 바이트('f'는 고정 소수점, 'e'는 지수, 'g'는 둘 중 짧은 쪽), 정밀도(-1은 "정확히 왕복하는 가장 적은 자릿수"를 뜻함), 원래 실수의 비트 크기(64 또는 32)를 받습니다.

strconv는 값을 인터페이스에 담아 fmt의 범용 형식화 경로를 거치는 fmt.Sprint보다 빠릅니다. 성능이 중요한 반복문에서는 차이가 드러나지만, 가끔 하는 변환이라면 읽기 좋은 쪽을 고르세요.

문자열을 숫자로 바꾸기

대상함수반환
intstrconv.Atoi(s)int, error
모든 부호 있는 정수strconv.ParseInt(s, base, bitSize)int64, error
모든 부호 없는 정수strconv.ParseUint(s, base, bitSize)uint64, error
실수strconv.ParseFloat(s, bitSize)float64, error
boolstrconv.ParseBool(s)bool, error

ParseInt는 항상 int64를 반환합니다. bitSize 인자(0, 8, 16, 32, 64)가 받아들이는 범위를 정하므로, 더 작은 타입으로 변환해도 결과가 반드시 들어맞습니다. base가 0이면 "접두사로 추론"한다는 뜻이라서 0x1f, 0o17, 0b101, 1_000이 모두 파싱됩니다.

출력에서 알 수 있는 것:

  • " 42"는 실패합니다. Atoi는 선택적인 부호와 숫자만 받고 그 외에는 받지 않습니다. bufio에서 온 입력은 보통 \n으로 끝나므로 잘라 내세요.
  • "4.2"Atoi에 유효하지 않습니다. 소수에는 ParseFloat를 쓰세요.
  • 범위를 벗어난 오류일 때 ParseInt는 오류와 함께 들어맞는 가장 큰 값(int8이면 127)을 반환합니다. 오류가 nil이 아니면 그 값을 쓰지 마세요.
  • 오류는 strconv.ErrSyntaxstrconv.ErrRange를 감싼 *strconv.NumError 값이므로 errors.Is로 구분할 수 있습니다.

ParseBool1, t, T, TRUE, true, True와 그에 대응하는 거짓 형태를 받습니다. "yes""on"은 오류입니다.

string(65) 함정

정수를 string으로 변환하면 숫자가 아니라 그 유니코드 코드 포인트에 해당하는 문자가 만들어집니다:

n := 65
s := string(n) // "A", not "65"

컴파일러는 받아들이지만 go vet이 보고합니다:

./main.go:10:7: conversion from int to string yields a string of one rune, not a string of digits

정말로 문자를 원한다면 룬으로 분명히 하세요: string(rune(n)). 숫자를 텍스트로 원한다면 strconv.Itoa(n)을 쓰세요. rune이나 bytestring으로 변환하는 것은 문제없고 흔한 일입니다:

문자열, 바이트, 룬

string, []byte, []runeT(v)로 서로 변환됩니다. 문자열은 불변이고 슬라이스는 그렇지 않으므로 변환할 때마다 데이터가 복사됩니다:

문자 단위로 인덱싱하거나 수정해야 한다면 []rune으로, 입출력, 해싱, 바이트 단위 편집에는 []byte로 변환하세요. UTF-8은 rune과 byte 페이지에서 자세히 다룹니다.

변환과 타입 단언

변환은 값을 한 구체 타입에서 다른 구체 타입으로 바꿉니다. 인터페이스(any, error, io.Reader)에서 구체 값을 꺼내는 것은 다른 연산인 타입 단언입니다:

var v any = 42

n := v.(int)       // type assertion: v holds an int, give it to me
f := float64(n)    // conversion: int to float64
// f := float64(v) // compile error: cannot convert v (variable of interface type any)
//                  // to type float64: need type assertion

먼저 단언하고, 그다음 변환하세요. comma-ok 형태 n, ok := v.(int)를 쓰면 타입이 틀렸을 때 패닉을 피할 수 있습니다.

빠른 참조

작업코드
int를 string으로strconv.Itoa(n)
int64를 string으로strconv.FormatInt(n, 10)
string을 int로n, err := strconv.Atoi(s)
string을 int64로n, err := strconv.ParseInt(s, 10, 64)
string을 float64로f, err := strconv.ParseFloat(s, 64)
float64를 string으로strconv.FormatFloat(f, 'f', -1, 64)
float64를 int로int(f) (절삭) 또는 int(math.Round(f))
int를 float64로float64(n)
string을 []byte로[]byte(s)
[]byte를 string으로string(b)
rune을 string으로string(r)
bool을 string으로strconv.FormatBool(b)
어떤 값이든 string으로fmt.Sprint(v)

자주 묻는 질문

Go에서 int를 string으로 바꾸려면 어떻게 하나요?

strconv.Itoa(n)을 씁니다: strconv.Itoa(42)"42"를 반환합니다. int64라면 strconv.FormatInt(n, 10)을 쓰세요. fmt.Sprint(n)도 모든 타입에 동작하지만 더 느립니다. string(n)이라고 쓰지 마세요. n을 유니코드 코드 포인트로 취급하므로 string(65)"A"가 됩니다.

Go에서 string을 int로 바꾸려면 어떻게 하나요?

숫자와 오류를 반환하는 strconv.Atoi를 씁니다:

n, err := strconv.Atoi("42")
if err != nil {
	// not a valid integer
}

특정 크기나 진법이 필요하면 int64를 반환하는 strconv.ParseInt(s, 10, 64)를 쓰세요. Atoi는 공백을 잘라 내지 않으므로 " 42"는 오류입니다. 먼저 strings.TrimSpace를 호출하세요.

Go에서 형변환(cast)은 어떻게 하나요?

Go에서는 변환(conversion)이라고 부르며, 문법은 T(v)입니다: float64(n), int(f), []byte(s). 숫자 타입 사이, 문자열과 바이트 슬라이스나 룬 슬라이스 사이, 기반 타입이 같은 타입 사이에서 동작합니다. 텍스트를 파싱하지는 않습니다. "42"42로 바꾸려면 strconv가 필요합니다. 인터페이스에서 구체 타입을 꺼내는 것은 변환이 아니라 타입 단언 v.(T)입니다.

Go에서 실수를 정수로 바꾸려면 어떻게 하나요?

int(f)는 0 쪽으로 절삭합니다: int(3.9)3이고 int(-3.9)-3입니다. 반올림하려면 int(math.Round(f))를 쓰세요. 실수가 정수 타입의 범위를 벗어나면 결과는 구현마다 다르므로, 값이 입력에서 온다면 먼저 범위를 확인하세요.

Go에서 string(65)가 "A"를 반환하는 이유는 무엇인가요?

정수를 string으로 변환하면 유니코드 코드 포인트로 해석되고, 65는 A의 코드 포인트입니다. go vet이 이를 지적합니다: conversion from int to string yields a string of one rune, not a string of digits. "65"를 얻으려면 strconv.Itoa(65)를 쓰세요.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기