Updated primitive-types.md

ziriso authored
revision 3542c2fb74d0a383d85ca340b35b39b29e991d4c
primitive-types
# 5.3. 기본형 (Primitive Types) - 0%

The Rust language has a number of types that are considered ‘primitive’. This
means that they’re built-in to the language. Rust is structured in such a way
that the standard library also provides a number of useful types built on top
of these ones, as well, but these are the most primitive.

# Booleans

Rust has a built in boolean type, named `bool`. It has two values, `true` and `false`:

```rust
let x = true;

let y: bool = false;
```

A common use of booleans is in [`if` conditionals][if].

[if]: if.html

You can find more documentation for `bool`s [in the standard library
documentation][bool].

[bool]: ../std/primitive.bool.html

# `char`

The `char` type represents a single Unicode scalar value. You can create `char`s
with a single tick: (`'`)

```rust
let x = 'x';
let two_hearts = '💕';
```

Unlike some other languages, this means that Rust’s `char` is not a single byte,
but four.

You can find more documentation for `char`s [in the standard library
documentation][char].

[char]: ../std/primitive.char.html

# Numeric types

Rust has a variety of numeric types in a few categories: signed and unsigned,
fixed and variable, floating-point and integer.

These types consist of two parts: the category, and the size. For example,
`u16` is an unsigned type with sixteen bits of size. More bits lets you have
bigger numbers.

If a number literal has nothing to cause its type to be inferred, it defaults:

```rust
let x = 42; // x has type i32

let y = 1.0; // y has type f64
```

Here’s a list of the different numeric types, with links to their documentation
in the standard library:

* [i8](../std/primitive.i8.html)
* [i16](../std/primitive.i16.html)
* [i32](../std/primitive.i32.html)
* [i64](../std/primitive.i64.html)
* [u8](../std/primitive.u8.html)
* [u16](../std/primitive.u16.html)
* [u32](../std/primitive.u32.html)
* [u64](../std/primitive.u64.html)
* [isize](../std/primitive.isize.html)
* [usize](../std/primitive.usize.html)
* [f32](../std/primitive.f32.html)
* [f64](../std/primitive.f64.html)

Let’s go over them by category:

## Signed and Unsigned

Integer types come in two varieties: signed and unsigned. To understand the
difference, let’s consider a number with four bits of size. A signed, four-bit
number would let you store numbers from `-8` to `+7`. Signed numbers use
“two’s complement representation”. An unsigned four bit number, since it does
not need to store negatives, can store values from `0` to `+15`.

Unsigned types use a `u` for their category, and signed types use `i`. The `i`
is for ‘integer’. So `u8` is an eight-bit unsigned number, and `i8` is an
eight-bit signed number.

## Fixed size types

Fixed size types have a specific number of bits in their representation. Valid
bit sizes are `8`, `16`, `32`, and `64`. So, `u32` is an unsigned, 32-bit integer,
and `i64` is a signed, 64-bit integer.

## Variable sized types

Rust also provides types whose size depends on the size of a pointer of the
underlying machine. These types have ‘size’ as the category, and come in signed
and unsigned varieties. This makes for two types: `isize` and `usize`.

## Floating-point types

Rust also has two floating point types: `f32` and `f64`. These correspond to
IEEE-754 single and double precision numbers.

# Arrays

Like many programming languages, Rust has list types to represent a sequence of
things. The most basic is the *array*, a fixed-size list of elements of the
same type. By default, arrays are immutable.

```rust
let a = [1, 2, 3]; // a: [i32; 3]
let mut m = [1, 2, 3]; // m: [i32; 3]
```

Arrays have type `[T; N]`. We’ll talk about this `T` notation [in the generics
section][generics]. The `N` is a compile-time constant, for the length of the
array.

There’s a shorthand for initializing each element of an array to the same
value. In this example, each element of `a` will be initialized to `0`:

```rust
let a = [0; 20]; // a: [i32; 20]
```

You can get the number of elements in an array `a` with `a.len()`:

```rust
let a = [1, 2, 3];

println!("a has {} elements", a.len());
```

You can access a particular element of an array with *subscript notation*:

```rust
let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3]

println!("The second name is: {}", names[1]);
```

Subscripts start at zero, like in most programming languages, so the first name
is `names[0]` and the second name is `names[1]`. The above example prints
`The second name is: Brian`. If you try to use a subscript that is not in the
array, you will get an error: array access is bounds-checked at run-time. Such
errant access is the source of many bugs in other systems programming
languages.

You can find more documentation for `array`s [in the standard library
documentation][array].

[array]: ../std/primitive.array.html

# Slices

A ‘slice’ is a reference to (or “view” into) another data structure. They are
useful for allowing safe, efficient access to a portion of an array without
copying. For example, you might want to reference just one line of a file read
into memory. By nature, a slice is not created directly, but from an existing
variable. Slices have a length, can be mutable or not, and in many ways behave
like arrays:

```rust
let a = [0, 1, 2, 3, 4];
let middle = &a[1..4]; // A slice of a: just the elements 1, 2, and 3
let complete = &a[..]; // A slice containing all of the elements in a
```

Slices have type `&[T]`. We’ll talk about that `T` when we cover
[generics][generics].

[generics]: generics.html

You can find more documentation for slices [in the standard library
documentation][slice].

[slice]: ../std/primitive.slice.html

# `str`

Rust’s `str` type is the most primitive string type. As an [unsized type][dst],
it’s not very useful by itself, but becomes useful when placed behind a reference,
like [`&str`][strings]. As such, we’ll just leave it at that.

[dst]: unsized-types.html
[strings]: strings.html

You can find more documentation for `str` [in the standard library
documentation][str].

[str]: ../std/primitive.str.html

# Tuples

A tuple is an ordered list of fixed size. Like this:

```rust
let x = (1, "hello");
```

The parentheses and commas form this two-length tuple. Here’s the same code, but
with the type annotated:

```rust
let x: (i32, &str) = (1, "hello");
```

As you can see, the type of a tuple looks just like the tuple, but with each
position having a type name rather than the value. Careful readers will also
note that tuples are heterogeneous: we have an `i32` and a `&str` in this tuple.
In systems programming languages, strings are a bit more complex than in other
languages. For now, just read `&str` as a *string slice*, and we’ll learn more
soon.

You can assign one tuple into another, if they have the same contained types
and [arity]. Tuples have the same arity when they have the same length.

[arity]: glossary.html#arity

```rust
let mut x = (1, 2); // x: (i32, i32)
let y = (2, 3); // y: (i32, i32)

x = y;
```

You can access the fields in a tuple through a *destructuring let*. Here’s
an example:

```rust
let (x, y, z) = (1, 2, 3);

println!("x is {}", x);
```

Remember [before][let] when I said the left-hand side of a `let` statement was more
powerful than just assigning a binding? Here we are. We can put a pattern on
the left-hand side of the `let`, and if it matches up to the right-hand side,
we can assign multiple bindings at once. In this case, `let` “destructures”
or “breaks up” the tuple, and assigns the bits to three bindings.

[let]: variable-bindings.html

This pattern is very powerful, and we’ll see it repeated more later.

You can disambiguate a single-element tuple from a value in parentheses with a
comma:

```
(0,); // single-element tuple
(0); // zero in parentheses
```

## Tuple Indexing

You can also access fields of a tuple with indexing syntax:


```rust
let tuple = (1, 2, 3);

let x = tuple.0;
let y = tuple.1;
let z = tuple.2;

println!("x is {}", x);
```

Like array indexing, it starts at zero, but unlike array indexing, it uses a
`.`, rather than `[]`s.

You can find more documentation for tuples [in the standard library
documentation][tuple].

[tuple]: ../std/primitive.tuple.html

# Functions

Functions also have a type! They look like this:

```
fn foo(x: i32) -> i32 { x }

let x: fn(i32) -> i32 = foo;
```

In this case, `x` is a ‘function pointer’ to a function that takes an `i32` and
returns an `i32`
90%

Rust 언어는 기본형(primitive)이라 여겨지는 많은 종류의 타입들을 가지고 있습니다. 이것들은 언어에 기본적으로 포함(built-in)된 것들입니다. 표준 라이브러리 또한 많은 유용한 타입들을 그 위에 쌓아올리는데, 이것들 또한 가장 근본적인 것들이며, Rust는 이런 식으로 조직되어 있습니다.

# 불린 자료형(Booleans)

Rust는 내장된 불린 자료형(boolean)을 가지고 있으며, 이를 `bool`이라 합니다. 여기에는 `true`와 `false`의 두가지 값이 가능합니다.

```rust
let x = true;

let y: bool = false;
```

가장 일반적인 사용 예는, [`if` 조건문][if]에 사용하는 것입니다.

[if]: if.html

`bool`에 대한 더 많은 문서들을 [표준 라이브러리 문서][bool]에서 찾아볼 수 있습니다.

[bool]: ../std/primitive.bool.html

# `char`

`char` 타입은 하나의 유니코드 스칼라 값을 표현합니다. 당신은 한 쌍의 작은 따옴표를 통해 `char`를 표현할 수 있습니다.

```rust
let x = 'x';
let two_hearts = '💕';
```

다른 언어와 다르게, Rust의 `char`은 1 byte가 아니며, 4 byte입니다.

`char`에 대한 다른 문서는 [표준 라이브러리 문서][char]에서 찾아볼 수 있습니다.

[char]: ../std/primitive.char.html

# 산술형(Numeric types)

러스트는 다양한 산술형(numeric type)을 지원하며 이는 몇가지로 분류(category) 가능합니다:
부호형(signed)과 무부호형(unsigned), 고정크기형(fixed)과 가변크기형(variable), 부동소수점형(floating-point)과 정수형.

이 타입들은 두가지 부분으로 구성되어 있습니다: 분류(category), 크기(size). 예를 들어, `u16`은 무부호형이며 16비트의 크기를 가집니다. 더 큰 크기를 가진다면 더 큰 숫자를 다룰 수 있습니다.

만약 숫자 상수(number literal)가 그 타입을 추론할만한 실마리를 가지고 있지 않다면, 그것들은 기본적으로 다음과 같이 됩니다:

```rust
let x = 42; // x has type i32

let y = 1.0; // y has type f64
```

여기에 다른 산술형들에 대한 목록이 있으며, 표준 라이브러리 문서에 대한 링크가 제공됩니다:

* [i8](../std/primitive.i8.html)
* [i16](../std/primitive.i16.html)
* [i32](../std/primitive.i32.html)
* [i64](../std/primitive.i64.html)
* [u8](../std/primitive.u8.html)
* [u16](../std/primitive.u16.html)
* [u32](../std/primitive.u32.html)
* [u64](../std/primitive.u64.html)
* [isize](../std/primitive.isize.html)
* [usize](../std/primitive.usize.html)
* [f32](../std/primitive.f32.html)
* [f64](../std/primitive.f64.html)

이제 분류에 따라 이것들을 검토해 봅시다.

## 부호형과 무부호형

정수형은 크게 두가지로 나눠볼 수 있습니다: 부호형과 무부호형. 이 차이를 이해하기 위해서, 4비트 크기의 숫자를 한번 생각해 봅시다. 4비트 부호형은 `-8`부터 `+7`까지 저장할 수 있게 해줍니다. 부호형은 "2의 보수 표현(two's complement representation)"을 사용할 것입니다. 4비트 무부호형은 음수를 저장할 필요가 없기에, `0`부터 `+15`까지 저장할 수 있습니다.

무부호형은 그 분류를 위해 `u`를 사용하며, 부호형은 `i`를 사용합니다. `i`는 `integer`를 의미합니다. 따라서 `u8`은 8비트 무부호형을 의미하며, `i8`은 8비트 부호형을 뜻합니다.

## 고정크기형(fixed size types)

고정크기형은 자신의 표현을 위해 미리 정해진 크기의 비트(bit)들을 사용합니다. 유효한 비트 크기는 `8`, `16`, `32`, `64`입니다. 따라서, `u32`는 무부호형 32비트 정수형이며, `i64`는 부호형 64비트 정수형입니다.

## 가변크기형(variable sized types)

Rust는 또한 기계가 한번에 처리할 수 있는 수의 크기(원문: the size of a pointer of the underlying maching)에 따라 그 크기가 달라지는 타입을 제공합니다. 이 타입들은 `size`로 분류되며, 부호형과 무부호형으로 나뉠 수 있습니다. 따라서 `isize`와 `usize`의 두 종류가 있습니다. (역자 주 : 프로그래머는 이 숫자형을 사용함으로써, 자신의 컴퓨터가 가장 빠르게 처리할 수 있는 숫자 크기를 사용할 수 있습니다. 이 데이터형은 C언어의 int와 unsigned에 해당합니다.)

## 부동 소수점형

Rust는 두가지 종류의 부동소수점형을 가지고 있습니다: `f32`와 `f64`. 이것은 IEEE-754 표준의 단정도(single-precision)와 배정도(double-precision) 표현과 관련이 있습니다.

# 배열

다른 많은 프로그래밍 언어와 마찬가지로, Rust는 데이터 묶음을 표현하기 위한 목록 자료형들을 제공합니다. 가장 기본적인 것은 *배열*로, 이는 같은 타입을 갖는 고정 크기의 목록을 뜻합니다. 기본적으로, 배열은 변경 불가능합니다.

```rust
let a = [1, 2, 3]; // a: [i32; 3]
let mut m = [1, 2, 3]; // m: [i32; 3]
```

배열은 `[T; N]`타입을 가집니다. `T` 표기법에 대해서는 [generics 절에서][generics] 이야기할 것입니다. `N`은 컴파일-타임 상수로, 배열의 길이를 뜻합니다.

배열을 같은 값으로 초기화하기 위한 간편한 방법이 있습니다. 아래의 예제에서 `a`의 각 원소는 `0`으로 초기화될 것입니다:

```rust
let a = [0; 20]; // a: [i32; 20]
```

배열 `a`에서 원소의 갯수를 얻기 위해서는 `a.len()`을 사용합니다.

```rust
let a = [1, 2, 3];

println!("a has {} elements", a.len());
```

배열 내부에서 특정 위치에 있는 원소에 접근하기 위하서는 *첨자 표기법(subscript notation)*을 사용합니다.

```rust
let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3]

println!("The second name is: {}", names[1]);
```

다른 대부분의 프로그래밍 언어와 마찬가지로, 첨자(subscript)는 0부터 시작하며, 따라서 가장 첫번째 원소의 이름은 `names[0]`이고, 두번째 원소는 `names[1]`입니다. 위의 예제는 `The second name is: Brian`을 출력합니다. 만약 당신이 배열의 첨자로 그 범위를 벗어난 수를 사용한다면, 에러가 발생합니다: 그 범위가 유효한지(bounds-check)는 실행시간(run-time)에 배열에 접근할 때 검사될 것입니다. 다른 시스템 프로그래밍 언어에서 이런 식의 잘못된 접근은 수많은 버그의 원흉입니다.

배열에 대한 더 많은 문서는 [표준 라이브러리 문서에서][array] 찾을 수 있습니다.

[array]: ../std/primitive.array.html

# 슬라이스

‘슬라이스(slice)’는 다른 데이터 구조에 대한 참조(혹은 단지 `보기`)입니다. 이것은 다른 배열의 일부분에 대해 복사 없이도 안전하고 효과적으로 접근할 수 있는 방법을 제공합니다. 예를 들면, 당신이 메모리로 읽어들인 파일 전체 중에 딱 한줄만을 참조하고 싶을 때가 있을 겁니다.
. 슬라이스는 이미 존재하는 다른 변수로부터 생성되며, 그 자신이 스스로 만들어질 수는 없습니다. 슬라이스는 길이를 가지며, 변경되거나 혹은 변경되지 않을 수 있고, 많은 부분에서 배열과 흡사하게 동작합니다.
```rust
let a = [0, 1, 2, 3, 4];
let middle = &a[1..4]; // A slice of a: just the elements 1, 2, and 3
let complete = &a[..]; // A slice containing all of the elements in a
```

슬라이스는 `&[T]`타입을 가집니다. `T`에 대해서는 [generics][generics] 항목에서 이야기할 것입니다.

[generics]: generics.html

슬라이스에 대한 더 많은 문서는 [표준 라이브러리 문서에서][slice] 찾을 수 있습니다.

[slice]: ../std/primitive.slice.html

# `str`

Rust의 `str` 타입은 가장 기본적인 문자열 타입입니다. [unsized type][dst]으로서, 이것은 그 자체로는 유용하지 않고, [`&str`][strings]와 같이 참조 뒤에 위치할 때 유용해집니다. As such, we’ll just leave it at that.

[dst]: unsized-types.html
[strings]: strings.html

`str`에 대한 더 많은 문서는 [표준 라이브러리 문서에서][str] 찾을 수 있습니다.

[str]: ../std/primitive.str.html

# 튜플(Tuples)

튜플은 다음과 같이, 고정 크기의 순서가 있는 목록입니다:

```rust
let x = (1, "hello");
```

괄호와 쉼표를 통해 2개 길이의 튜플을 형성했습니다. 여기에 똑같은 코드가 있는데, 여기서는 타입을 지정한 점이 다릅니다.

```rust
let x: (i32, &str) = (1, "hello");
```

As you can see, the type of a tuple looks just like the tuple, but with each
position having a type name rather than the value. 주의깊은 독자라면 튜플은 잡종(heterogeneous)인 것에 주목할 것입니다: 위의 튜플은 `i32`와 `&str`을 가집니다. 다른 언어일때보다 시스템 프로그래밍 언어일 때, 문자열은 좀 더 복잡한 문제가 됩니다. 지금은, `&str`을 *string slice*로 읽는다는 것만 알아두시고, 이에 대해서는 곧 자세히 배우게 될 것입니다.

당신은 두 튜플이 동일한 타입들을 포함하고 있고 동일한 [arity]일 때, 한 튜플을 다른 튜플에 대입(assign)할 수 있습니다. 두 튜플은 동일한 길이를 가질때 동일한 [arity]를 가집니다.

[arity]: glossary.html#arity

```rust
let mut x = (1, 2); // x: (i32, i32)
let y = (2, 3); // y: (i32, i32)

x = y;
```

*destructuring let*을 통해, 튜플 안의 특정 필드(field)에 접근할 수 있습니다. 아래는 그 예제입니다.

```rust
let (x, y, z) = (1, 2, 3);

println!("x is {}", x);
```

[예전에][let] let 구문(statement)의 좌변은 단지 바인딩을 대입하는 것보다 더 강력하다고 말한 것을 기억합니까? 바로 이것입니다. 우리는 `let`의 좌변에 패턴을 놓을 수 있고, 만약 그것이 우변과 잘 맞아 떨어진다면, 우리는 여러개의 바인딩을 한번에 대입할 수 있습니다. 이 경우에, `let`은 튜플을 "destructure"하거나 "break up"해서, 3개의 바인딩을 각자 만들게 됩니다.

[let]: variable-bindings.html

이 패턴은 아주 강력하며, 앞으로도 보고 또보고 하게 될 겁니다.

원소가 하나뿐인 튜플과 괄호 내의 값의 차이점을 잘 구분하시길 바랍니다.

```
(0,); // single-element tuple
(0); // zero in parentheses
```

## 튜플 인덱싱

인덱싱 구문을 통해, 튜플 내의 필드(field)에 접근할 수 있습니다.

```rust
let tuple = (1, 2, 3);

let x = tuple.0;
let y = tuple.1;
let z = tuple.2;

println!("x is {}", x);
```

배열의 인덱싱과 마찬가지로, 튜플의 인덱싱도 0부터 시작하지만, 배열과는 다르게
`[]`대신 `.`을 사용합니다.

튜플에 대한 더 자세한 문서는 [표준 라이브러리 문서에서][tuple] 찾을 수 있습니다.

[tuple]: ../std/primitive.tuple.html

# 함수

함수 또한 타입입니다! 아래를 보십시오:

```
fn foo(x: i32) -> i32 { x }

let x: fn(i32) -> i32 = foo;
```

이 경우에, `x`는 함수를 가리키는 함수 포인터이며, `i32`를 취하고 `i32`를 반환하게 됩니다
.