정수 리터럴
정수 리터럴
코드에서 숫자 값이 필요할 때, 우리는 보통 42처럼 10진법으로 적어요. 그런데 색상 코드나 접근 권한 비트처럼 2진법·16진법으로 보는 게 훨씬 자연스러운 값들도 꽤 있죠. Go가 이런 상황에서 어떤 표기를 지원하는지, 또 숫자 사이에 밑줄(_)을 넣는 게 어떤 의미인지, 실제 리터럴 예시와 함께 하나씩 살펴볼게요.
출처: Go Specification
본문
정수 리터럴(integer literal)은 정수 상수를 나타내는 숫자의 나열이에요. 선택적인 접두사를 붙이면 10진법이 아닌 다른 진법을 지정할 수 있어요.
0b또는0B는 2진법을 뜻해요.0,0o, 또는0O는 8진법을 뜻해요.0x또는0X는 16진법을 뜻하죠 [Go 1.13].
여기서 단독으로 쓰인 0 하나는 10진법의 0으로 취급합니다. 그리고 16진법 리터럴에서는 문자 a부터 f, A부터 F까지가 각각 값 10부터 15를 나타내요.
읽기 좋게 하려는 목적으로, 밑줄 문자 _를 밑줄 접두사 뒤나 연속된 숫자 사이에 넣을 수 있어요. 이런 밑줄은 리터럴의 값을 바꾸지 않아요. 아래 EBNF가 정확한 문법을 보여주는데, 자세히 보면 밑줄이 어디에 들어갈 수 있는지가 명확하게 드러나요.
int_lit = decimal_lit | binary_lit | octal_lit | hex_lit .
decimal_lit = "0" | ( "1" … "9" ) [ [ "_" ] decimal_digits ] .
binary_lit = "0" ( "b" | "B" ) [ "_" ] binary_digits .
octal_lit = "0" [ "o" | "O" ] [ "_" ] octal_digits .
hex_lit = "0" ( "x" | "X" ) [ "_" ] hex_digits .
decimal_digits = decimal_digit { [ "_" ] decimal_digit } .
binary_digits = binary_digit { [ "_" ] binary_digit } .
octal_digits = octal_digit { [ "_" ] octal_digit } .
hex_digits = hex_digit { [ "_" ] hex_digit } .
이제 실제 예시를 볼게요. 같은 값을 밑줄을 넣고 빼고, 서로 다른 진법으로 적은 모습이에요.
42
4_2
0600
0_600
0o600
0O600 // second character is capital letter 'O'
0xBadFace
0xBad_Face
0x_67_7a_2f_cc_40_c6
170141183460469231731687303715884105727
170_141183_460469_231731_687303_715884_105727
_42 // an identifier, not an integer literal
42_ // invalid: _ must separate successive digits
4__2 // invalid: only one _ at a time
0_xBadFace // invalid: _ must separate successive digits
예시 끝부분의 주석을 꼭 한 번 읽어보세요. 여기서 규칙의 경계가 드러나요. _42는 밑줄이 맨 앞에 붙어서 정수 리터럴이 아니라 식별자(identifier) 가 되어 버려요. 42_처럼 숫자가 밑줄로 끝나면, 4__2처럼 밑줄이 두 번 겹치면, 0_xBadFace처럼 접두사 바로 뒤에 밑줄이 오면 모두 잘못된 문법이에요. 밑줄은 오직 연속된 숫자를 구분하는 데만 쓰인다는 점이 핵심이죠.
더 알아보기
- 정수 상수 (Constants) — 리터럴이 나타내는 값의 타입과 상수 규칙을 더 알아보고 싶을 때 봐요.
- 플로팅 포인트 리터럴 (Floating-point literals) — 소수점이 있는 숫자 리터럴도 같은 패턴으로 밑줄과 접두사를 써요.
- Go 1.13 릴리스 노트 — 2진법·8진법·16진법 접두사와 밑줄 표기가 어떤 계기로 도입됐는지 참고할 수 있어요.