Menu

Zero 원시 타입: 정수, 실수, Bool, String, Void

Zero가 기본으로 제공하는 내장 타입들. 모든 너비의 부호 있는·부호 없는 정수, 실수, 불리언, 문자, 문자열, 그리고 빈 타입 Void까지 정리했습니다.

내장 타입들

Zero는 작고 규칙적인 원시 타입 모음을 제공합니다. 별스러운 것도, 놀랄 만한 것도 없이 시스템 언어가 필요로 하는 것들을 일관된 이름으로 제공할 뿐입니다.

분류타입비고
부호 있는 정수i8, i16, i32, i642의 보수.
부호 없는 정수u8, u16, u32, u640과 양수만.
포인터 크기usize, isize플랫폼 포인터 너비에 맞춰짐.
실수f32, f64IEEE-754.
불리언booltrue 또는 false.
문자char유니코드 스칼라 하나.
문자열StringUTF-8 문자열.
빈 타입Void"유용한 값 없음".

일상적으로 만나게 될 원시 타입 목록은 이게 전부입니다. 복합 타입 — shape, enum, choice — 은 이것들을 토대로 만들어집니다.

정수

정수 타입은 일관된 명명 규칙을 따릅니다. 부호 있는 것은 i, 부호 없는 것은 u, 그 뒤에 비트 너비가 옵니다. 그러니까 i32는 32비트 부호 있는 정수, u8은 부호 없는 바이트, i64는 64비트 부호 있는 정수죠.

let small_signed: i8   = -120
let byte:         u8   = 250
let id:           i32  = 1
let big:          i64  = 9_000_000_000
let index:        usize = 0

접미사 없는 리터럴의 기본값은, 주변 문맥이 다른 것을 강제하지 않는 한 i32입니다.

let answer = 42       // i32

특정 너비가 필요할 때는 리터럴에 접미사를 붙이거나 바인딩에 어노테이션을 답니다.

let byte = 250_u8     // 타입 접미사 리터럴
let byte: u8 = 250    // 타입을 단 바인딩

두 형태 모두 같은 값을 만들어 냅니다. 리터럴 접미사 형태는 리터럴을 함수에 직접 전달하거나 구조체를 만들 때 편리합니다.

let pair: BytePair = Pair { left: 1_u8, right: 2_u8 }

어떤 너비를 고를까

간단한 가이드라인:

  • 부호 있는 산술은 대부분 i32. 거의 모든 카운트에 충분히 넓고, 어느 플랫폼에서나 빠릅니다.
  • 바이트 단위 작업은 u8. 파일에서 읽은 바이트, 버퍼의 바이트, 네트워크에서 받은 바이트 등.
  • 범위가 중요한 음수가 아닌 카운트는 u32 / u64. 2GB를 넘는 파일 오프셋, 큰 카운트 등.
  • 크기와 인덱스는 usize. 포인터 크기이며, 플랫폼이 메모리 주소에 사용하는 것과 같습니다.
  • 에포크 이후 시간 등에는 i64. 수백 년 어치의 나노초도 담을 만큼 충분히 큽니다.

들어가는 가장 작은 타입을 고르는 게 좋은 관행이지만, 너무 작은 타입을 골라 오버플로우가 나는 것보다는 한 비트 정도 넉넉한 타입을 고르는 편이 훨씬 안전합니다.

불리언

let ok = true
let done: bool = false

bool은 정확히 두 값을 가집니다. truefalse. 어디서 import해 오는 상수가 아니라 리터럴이에요. ifwhile의 조건은 bool이어야 합니다. 정수나 문자열이 암묵적으로 참/거짓이 되는 일은 없습니다.

if ok {
    check world.out.write("yes\n")
} else {
    check world.out.write("no\n")
}

조건문은 if/else에서 자세히 다룹니다.

실수

f32f64는 각각 32비트와 64비트 IEEE-754 부동소수점 숫자입니다. 측정값, 비율, 기하학처럼 분수 값이 필요할 때 사용하세요. 통화 같은 곳에서 정확한 산술이 필요하다면, 실수 대신 가장 작은 단위(센트, 사토시)의 정수를 쓰는 편이 좋습니다.

let ratio: f32 = 0.5
let pi:    f64 = 3.141592653589793

접미사 없는 실수 리터럴의 기본값은 f64입니다.

문자와 문자열

char는 단일 유니코드 스칼라 값을 담습니다.

let initial: char = 'Z'

String은 문자의 시퀀스이고, 표준 라이브러리에서 보통 UTF-8로 인코딩됩니다. 문자열 리터럴은 큰따옴표를 씁니다.

let message: String = "hello from zero\n"

예상할 수 있는 이스케이프 시퀀스가 모두 동작합니다. 줄바꿈은 \n, 탭은 \t, 리터럴 백슬래시는 \\, 리터럴 큰따옴표는 \".

let multi_line = "line one\nline two\n"

표준 라이브러리는 낮은 수준 작업을 위해 문자열을 바이트 단위로 보는 뷰를 노출합니다. std.mem.span("zero") 형태는 바이트에 대한 Span<u8>을 반환합니다. 파싱, 해싱, 바이트 단위 비교에 유용해요.

Void

Void는 Zero의 "유용한 반환 값이 없음" 타입입니다. 부수 효과를 위해 존재하는 함수가 사용합니다.

pub fun main(world: World) -> Void raises {
    check world.out.write("hello\n")
}

main은 무언가를 쓴 뒤 반환합니다. 돌려줄 값이 없으니 타입은 Void입니다. World를 다루는 대부분의 함수에서 Void를 보게 되실 거예요. 결과가 아니라 효과를 위해 선택된 함수들이기 때문이죠.

숫자 리터럴의 언더스코어

긴 숫자 리터럴은 시각적 구분자로 언더스코어를 쓸 수 있습니다. 컴파일러는 무시하므로 순수한 가독성 기능입니다.

let big   = 9_000_000_000_i64
let bytes = 1_048_576_u32     // 1 MiB

자릿수가 세기 어려워지는 곳이라면 어디든 끼워 넣으세요.

타입 리터럴 접미사 치트시트

접미사타입예시
_i8 / _i16 / _i32 / _i64부호 있는 정수127_i8
_u8 / _u16 / _u32 / _u64부호 없는 정수255_u8
_usize / _isize포인터 크기0_usize
_f32 / _f64실수0.5_f32

주변 문맥이 타입을 결정해 주지 못하는 곳에서 값을 만들 때 활용하세요.

다음 글: 함수

원시 타입만으로는 할 수 있는 일이 없습니다. 다음 문서에서는 Zero의 함수를 다룹니다. 어떻게 선언하고, 값을 반환하고, 모아서 실제 프로그램을 만드는지 살펴봅니다.

자주 묻는 질문

Zero에는 어떤 원시 타입이 있나요?

Zero는 부호 있는 정수 i8, i16, i32, i64, 부호 없는 정수 u8, u16, u32, u64, 포인터 크기 정수 usizeisize, 실수 f32f64, bool, char, String, 그리고 유용한 값을 반환하지 않는 함수를 위한 Void를 기본 제공합니다.

Zero의 기본 정수 타입은 무엇인가요?

42처럼 접미사가 없는 정수 리터럴은 문맥이 다른 타입을 강제하지 않는 한 i32로 기본 설정됩니다. 특정 너비를 쓰려면 42_u8이나 42_i64처럼 접미사를 붙이거나, let count: u8 = 42처럼 바인딩 타입을 명시적으로 적으세요.

Zero에는 별도의 문자열 타입이 있나요?

네. "hello" 같은 문자열 리터럴은 표준 라이브러리가 바이트 시퀀스(주로 UTF-8)로 다루는 내장 문자열 타입을 가집니다. 더 낮은 수준의 바이트 작업이 필요하면 표준 라이브러리에 스팬과 바이트 단위 유틸리티가 있고, 문자 단위 처리가 필요하면 개별 스칼라 값을 위한 char가 있습니다.

Zero에서 Void는 무슨 뜻인가요?

Void는 유용한 값을 만들어내지 않는 함수의 반환 타입입니다. 부수 효과를 위해 존재하는 함수죠. 관습적인 pub fun main(world: World) -> Void raises 시그니처는 main이 I/O를 하고 종료하는 함수이지 값을 만들어 내는 함수가 아니기 때문에 Void를 씁니다.

Zero의 i32와 u32는 어떻게 다른가요?

i32는 부호 있는 32비트 정수로, 범위는 −2,147,483,648부터 2,147,483,647까지입니다. u32는 부호가 없고 0부터 4,294,967,295까지의 범위를 가집니다. 음수가 의미 있는 값일 때는 부호 있는 타입을, 음수가 버그를 의미하는 경우(카운트, 인덱스, 크기 등)에는 부호 없는 타입을 쓰세요.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기