Rust, 일반적인 프로그래밍 개념

생성일
Oct 6, 2024 09:38 AM
태그
<러스트 프로그래밍 공식 가이드>(2판)의 2장 내용을 정리했다.
 

변수와 상수

변수

  • Rust에서 변수는 기본적으로 불변. mutable하게 만들 수 있음.
  • mut prefix를 이용해 변수를 가변으로 선언 가능 (let mut x = 5;)
 

상수

  • const로 선언하며 불변. 선언시 타입을 반드시 명시해야 함.
  • 전역 스코프를 포함한 모든 스코프에서 선언 가능
  • 상수는 상수 표현식으로만 설정되며, 런타임에서 계산할 수 있는 값은 할당 불가.
  • THREE_HOURS_IN_SECONDS처럼 표현하는 것이 관례
 

Shadowing

  • 동일한 스코프 안에서 동일한 이름의 변수를 중복 선언하는 것이 가능하며 이 경우 가장 마지막에 선언된 변수가 유효하다.
  • 서로 다른 타입으로도 섀도잉 가능하다.
fn main() { let x = 5; let x = x + 1; let x = "leon"; }
  • 변수의 값을 mutable하게 하는 것이 아니다. 값은 변형하되, 변경 후에는 불변으로 유지한다는 점이 다르다. 그리고 다른 타입으로도 재선언 가능한 점도 다르다.
 

데이터 타입

Rust는 정적 타입 언어다. 컴파일 시점에 모든 변수의 타입이 결정된다.

스칼라

  • 정수형 (기본값은 i32)
    • 부호 있는 타입: ~
    • 부호 없는 타입: 0 ~
  • 부동소수점 (default = f32, f64)
  • 참고) 모듈러 연산: %
  • 불리언 (bool)
  • 문자 (char): 작은 따옴표. 4byte(유니코드)

복합타입

  • 튜플 (각 요소가 서로 다른 타입일 수 있음)
    • let tup = (500, 6.4, 1); let (x, y, z) = tup; // destructuring 지원 let five_hundred = tup.0; // .으로 오프셋 접근 let six_point_four = tup.1;
    • 빈 튜플은 unit으로 불리며 표현식의 반환값이 없으면 암묵적으로 unit 값을 반환
  • 배열 (각 요소는 모두 같은 타입)
    • let a = [1, 2, 3, 4, 5]; let first = a[0]; let second = a[1]; let sixth = a[5]; // run time error: panic
 

함수

  • Rust는 함수의 위치를 고려하지 않기 때문에 A함수보다 B 함수가 밑에 있어도 A함수에서 B함수를 실행할 수 있음.
    • // 반환값을 갖는 함수 fn five() -> i32{ // return이 없어도 마지막 표현식을 암묵적으로 반환. 5 // 세미콜론이 붙으면 표현식이 아닌 구문으로 이해해서 에러가 발생. }
 

구문과 표현식

  • 구문(statement): 동작을 수행하지만 값을 반환하지 않는 명령
  • 표현식: 결과값을 평가.
 
fn main() { let y = { let x = 3; x + 1 // x에 1을 더한 값이 반환되어 y에 저장됨 }; }
 

제어흐름

if

  • if
  • else if
  • else
  • 삼항연산자
if number % 4 == 0 { // logic } else if number == 5 { // logic } else { // logic } // 아래는 에러가 발생: 반드시 if문에는 bool 값만 올 수 있음. let x = 5; if x { // logic } // 삼항 연산자도 가능 let num = if x > 6 { 5 } else { 1 } // 각 갈래의 결과값은 같은 타입이어야 함
 

반복문

  • loop
    • loop { // 무한반복 } // 반복문에서 값 반환 let mut counter = 0; let result = loop { counter += 1; if counter == 10 { break counter * 2; } } // 루프에 라벨 붙이기 let mut count = 0; "counting_up": loop { let mut remaining = 10; loop { if remaining == 9 { break; } if count == 2 { // 루프 라벨을 이용해 바깥쪽 루프 종료 break "counting_up"; } remaining -= 1; } count += 1; }
  • while (조건과 함께 반복)
    • let mut number = 3; while number != 0 { number -= 1; }
  • for
    • while문으로 for 루프를 대체할 수 있지만, 매 루프마다 인덱스 체크를 컴파일러가 해야해서 느려짐.
    • 개발자 실수로 인한 index out of range로 panic이 나는 케이스 방지 가능
    • // while문으로 for 루프를 대체할 수 있지만, 매 루프마다 인덱스 체크를 컴파일러가 해야해서 느려짐. // for문이 나온 배경 let a = [10, 20, 30, 40]; for element in a { println!("value: {element}"); } // count down! for number in (1..4).rev() { // 3!, 2!, 1! 만약 4를 포함하고 싶으면 (1..=4)로 표시 println("{number}!"); }