https://doc.rust-lang.org/book/
https://rinthel.github.io/rust-lang-book-ko/
기본적으로 compile과 run은 개별적인 단계이다.
컴파일이 성공적으로 되면, 러스트는 실행가능한 바이너리를 출력한다.
rustc main.rs // 바이너리 main생성
./main //바이너리 실행
rust의 가장 큰 특징이라고 할 수 있는 소유권개념은
러스트가 가비지 콜렉터 없이 메모리 안정성 보장을 하게 해준다.
자세한 내용은 향후 진도를 통해 학습한다.
hello world 출력함수를 작성한 뒤 위에서 언급한 compile과 run을 하게되면
해당내용이 정상적으로 출력 되는것을 확인할 수 있다.
fn main() {
println!("Hello, world!");
}
rustc main.rs
./main
-> Hello, world!
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이 있다.
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키워드를 다시 사용하여 새 변수를 선언하여
값의 유형을 변경할 수 있으면서도 동일 이름을 사용할 수 있다는 점이다.
상수에 대해서는 mut접두어를 사용하는것이 허용되지 않으며
당연히 값을 재할당 하는것이 허용되지 않는다.
const MAX_POINTS: u32 = 100_000;
데이터타입은 크게 스칼라타입과 복합타입이 존재한다.
소수점이 없는 숫자. 부호 여부에 따라 u,i로 구분된다.
Length | Signed | Unsigned |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
arch | isize | usize |
부호여부
i (signed) : -2^(n-1) ~ 2^(n-1)
u (unsigned) : 0 ~ 2^n
ex)
i8 : -128 ~ +127
u8 : 0 ~ 255
소수점을 갖는 숫자. f32, f64 두가지의 타입이 존재한다. 기본타입은 f64이다. 부동소수점 숫자는 IEEE-754 표준에 따라 표현된다.
let x = 2.0; // f64
let y: f32 = 3.0; // f32
let t = true;
let c = 'z';
튜플은 다양한 타입의 몇 개의 숫자를 집합시켜 하나의 복합 타입으로 만드는 일반적인 방법이다.
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
let a = [1, 2, 3, 4, 5];
위에서 설명했듯이 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