참고자료

https://doc.rust-lang.org/book/
https://rinthel.github.io/rust-lang-book-ko/


rust의 특징

compile 과 run 의 분리

기본적으로 compile과 run은 개별적인 단계이다.
컴파일이 성공적으로 되면, 러스트는 실행가능한 바이너리를 출력한다.

rustc main.rs // 바이너리 main생성
./main  //바이너리 실행

ownership 의 존재

rust의 가장 큰 특징이라고 할 수 있는 소유권개념은
러스트가 가비지 콜렉터 없이 메모리 안정성 보장을 하게 해준다.
자세한 내용은 향후 진도를 통해 학습한다.

hello, world !

hello world 출력함수를 작성한 뒤 위에서 언급한 compile과 run을 하게되면
해당내용이 정상적으로 출력 되는것을 확인할 수 있다.

fn main() {
    println!("Hello, world!");
}
rustc main.rs
./main
-> Hello, world!

Variables and Mutability - 변수와 가변성

Immutabale

rust의 변수는 기본적으로 immutable(불변성) 이다.
일단 값이 이름에 bound되면 해당 값을 변경할 수 없다.
아래와 같이 immutable변수에 재할당 하게되면 에러가 발생하게 된다.

let x = 5;
x = 6;
// -> error[E0384]: cannot assign twice to immutable variable `x`

접두어로 mut을 추가한다면 가변성 변수를 선언할 수 있다.
즉, x의 값을 재할당 할 수 있다.

let mut x = 5;
x = 6;

Shadowing

변수의 값을 변경하는 방법은 shadowing이 있다.
mut과 비슷해보이지만 차이점이 존재한다.

let x = 5;
let x = x + 1;
let x = x * 2;
println!("The value of x is: {}", x);

rust는 기본적으로 타입이 고정된 언어이다. 타입을 지정하지 않을시, 처음입력되는 값의 데이터타입으로 타입이 지정되므로 mut 변수를 선언하게 되어도 다른타입의 값을 대입하게 되면 에러가 발생하게 된다.

//mut
let mut spaces = "string";
spaces = spaces.len(); // -> Error
//error[E0308]: mismatched types

//shadowing
let spaces = "string";
let spaces = spaces.len(); // -> Ok

즉, mut과 shadowing의 차이는 let키워드를 다시 사용하여 새 변수를 선언하여
값의 유형을 변경할 수 있으면서도 동일 이름을 사용할 수 있다는 점이다.

Const

상수에 대해서는 mut접두어를 사용하는것이 허용되지 않으며
당연히 값을 재할당 하는것이 허용되지 않는다.

const MAX_POINTS: u32 = 100_000;

Data Types - 데이터 타입들

데이터타입은 크게 스칼라타입과 복합타입이 존재한다.

  • Scalar : 하나의 값으로 표현되는 타입 (정수형, 부동소숫점, boolean, 문자)
  • Compound : 다른 타입의 값들을 하나의 타입으루 묶을 수 있다 (튜플, 배열)

Scalar Types

1. 정수형(Integer)

소수점이 없는 숫자. 부호 여부에 따라 u,i로 구분된다.

LengthSignedUnsigned
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
archisizeusize

부호여부

i (signed) : -2^(n-1) ~ 2^(n-1)
u (unsigned) : 0 ~ 2^n

ex)

i8 : -128 ~ +127
u8 : 0 ~ 255

2. 부동 소수점 타입(Floating-Point)

소수점을 갖는 숫자. f32, f64 두가지의 타입이 존재한다. 기본타입은 f64이다. 부동소수점 숫자는 IEEE-754 표준에 따라 표현된다.

let x = 2.0; // f64
let y: f32 = 3.0; // f32

3. Boolean

let t = true;

4. 문자타입

let c = 'z';

Compound Types

1. Tuple 튜플

튜플은 다양한 타입의 몇 개의 숫자를 집합시켜 하나의 복합 타입으로 만드는 일반적인 방법이다.

let tup = (500, 6.4, 1);
let tup2: (i32, f64, u8) = (500, 6.4, 1);
let (x, y, z) = tup;

다음과 같이 튜프를 선언 후 (.)뒤에 index값을 입력하여 접근할 수 있다.
예를들면 let x = (500, 6.4, 1)일 경우 x.1=6.4가 된다.

let x: (i32, f64, u8) = (500, 6.4, 1);
    
let five_hundred = x.0; //0번째 값 500
let six_point_four = x.1; //1번째 값 6.4
let one = x.2; // 2번째 값 1

2. Array 배열

let a = [1, 2, 3, 4, 5];

과제

overflow

위에서 설명했듯이 rust의 정수형은 타입에 따라 기본적으로 할당된 값이 다르다.
이 값을 초과했을경우 overflow 에러가 발생하게된다.

예를들어, 0~255 까지의 값을 가지는 u8정수형의 경우
255+1 혹은 0-1 을 하게되면 overflow에러가 발생한다.

println!("{}", 255_u8+1_u8);
// attempt to compute `u8::MAX + 1_u8`, which would overflow
println!("{}", 0_u8-1_u8);
// attempt to compute `0_u8 - 1_u8`, which would overflow

범위를 초과하였으니 에러가 나는것이 정상이지만, 이러한 에러를 없애고싶다면 wrapping_sub, wrapping_add와 같은 function을 사용하는 방법이 있다.

u8 정수형 타입의 경우, 255 + 1 = 0 혹은 0 - 1 = 255
과 같이 작동한다.

초과하는 범위를 넘어가면 다시 0으로 돌아와서 계산하므로 사용에 유의해야한다.

println!("{}", 255_u8.wrapping_add(1)); // 0
println!("{}", 0_u8.wrapping_sub(1)); // 255

각 타입이 표현할 수 있는 최대값과 최소값은 u8::MAX,u8::MIN 와 같이 표현할 수도 있다.

println!("{}", u8::MAX); // 255
println!("{}", u8::MIN); // 0
println!("{}", i8::MAX); // 127
println!("{}", i8::MIN); // -128

0개의 댓글