반응형

[Rust] 18

[Rust] 라이프타임(lifetime)

: 어떤 참조자가 필요한 기간 동안 유효함을 보장합니다. 러스트의 모든 참조자는 라이프타임 범위를 가지며, 라이프타임은 암묵적으로 추론됩니다. 이 라이프타임을 명시해야 하는 경우에 대해 알아보겠습니다. - 라이프 타임으로 댕글링 참조 방지 라이프타임의 주목적은 댕글링 참조(dangling reference) 방지입니다. 러스트 컴파일러는 대여 검사기(borrow checker)를 스코프로 비교해서 대여의 유효성을 판단합니다. 'b(참조 대상)가 'a(참조자)보다 짧기 때문에 이 코드는 컴파일되지 않습니다. fn main() { let r; // ---------+-- 'a //r의 라이프타임 // | { // | let x = 5; // -+-- 'b | // x의 라이프타임 r = &x; // | | ..

[Rust] 2023.08.19

[Rust] 트레이트(trait)

: 타입들이 공통적으로 갖는 동작을 추상적으로 정의한 것입니다. trait bound를 이용하면 어떤 제네릭 타입 자리에 특정한 동작의 타입이 오도록 명시할 수 있습니다. - 트레이트 구현 trait를 정의하고, 어떤 구조체(NewArticle)가 trait를 구현하도록 지정한 예시 코드입니다. trait의 메서드는 선언부만 정의할수도, 구현체까지 정의할 수도 있으며, 기본 동작을 유지할지 override할지 선택할 수 있습니다. 예시 코드에서는 트레이트에서 summarize() 함수의 선언부만 정의한 후, NewArticle에서 오버라이드했습니다. // 신문 기사를 요약해주는 trait 구현 trait Summary { // 선언부만 정의 fn summarize(&self) -> String; } //..

[Rust] 2023.08.18

[Rust] 제네릭 타입

: 중복되는 개념을 효율적으로 처리하기 위한 도구입니다. 제네릭은 구체(concrete) 타입 또는 기타 속성에 추상화된 대역입니다. Option, Vec, HashMap, Result 등등이 모두 제네릭을 사용한 것입니다(T). 제네릭을 사용해서 함수, 구조체, 열거형, 메서드를 각각 정의하는 방법을 알아보겠습니다. 1) 제네릭 함수 슬라이스에서 가장 큰 값을 참조하는 함수입니다. fn largest(list: &[T]) -> &T { let mut largest = &list[0]; for item in list { if item > largest { largest = item; } } largest } * 트레이트 : 타입들이 공통적으로 갖는 동작을 추상화해줍니다. 트레이트에 대해서는 다음 챕터에서..

[Rust] 2023.08.17

[Rust] 에러 처리

러스트는 에러를 복구 가능한 에러, 복구 불가능한 에러 두 범주로 나눕니다. 대부분의 언어는 예외처리 메커니즘을 쓰는데 러스트에는 이 기능이 없는 대신, 복구 가능한 에러를 위한 Result 타입이 있고 복구 불가능한 에러가 발생하면 프로그램을 종료하는 panic! 매크로가 있습니다. 1) panic! 으로 복구 불가능한 에러 처리 패닉을 일으키는 방법에는 패닉을 일으킬 동작을 하는 것과 panic! 매크로를 명시적으로 호출하는 방법이 있습니다. 패닉은 실패 메시지를 출력하고, 되감고(unwind), 스택을 청소하고, 종료합니다. 패닉이 발생하면 근원을 쉽게 추적하기 위해 환경 변수를 통해 러스트가 호출 스택을 보여주도록 할 수 있습니다. * unwinding : panic!이 발생했을 때 러스트가 패닉..

[Rust] 2023.08.16

[Rust] match 연산자

: 흐름 제어 연산자로, 일련의 패턴에 대해 어떤 값을 비교한 뒤 어떤 패턴에 매치되었는지를 바탕으로 코드를 수행하게 해줍니다. match의 힘은 패턴의 표현성으로부터 오며, 컴파일러는 모든 가능한 경우가 다루어지는지를 검사합니다. 다음은 코인의 종류를 enum으로 표현하고, 코인을 센트로 변환해주는 함수입니다. match에서의 각각 나뉘는 갈래를 arm이라 합니다. enum Coin { Penny, Nickel, Dime, Quarter, None, } fn value_in_cents(coin: Coin) -> u32 { match coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter => 25, Coin::None =>..

[Rust] 2023.08.15

[Rust] 컬렉션(Collection)

: 러스트 표준 라이브러리의 유용한 데이터 구조로, 다수의 값을 담을 수 있습니다. 배열이나 튜플과는 달리 힙에 저장되는데 이는 프로그램 실행 중에 데이터의 양이 늘거나 줄어들 수 있음을 의미합니다. 러스트 프로그램에서 자주 사용되는 컬렉션에는 다음 세가지가 있습니다. 벡터(vector) : 여러 개의 값을 서로 붙어서 저장될 수 있게 해줍니다. 문자열(string) : 문자(character)의 모음입니다. 해시맵(hash map) : 어떤 값을 특정 키와 연관지어 주도록 해줍니다. 1) 벡터(vector) - Vec 같은 타입의 값만 저장 가능하며, 모든 값을 메모리에서 연속적으로 배치합니다. - 새 벡터 만들기 : 비어있는 벡터를 만들기 위해서 Vec::new 함수를 호출합니다. 벡터에 어떤 값도 ..

[Rust] 2023.08.14

[Rust] 패키지, 크레이트, 모듈로 프로젝트 관리

프로젝트 규모가 커지면 코드를 여러 모듈, 파일로 나눠서 관리해야 합니다. 한 패키지는 여러 개의 바이너리 크레이트와 라이브러리 크레이트를 포함할 수 있고, 커진 프로젝트의 각 부분을 크레이트로 나눠서 외부 라이브러리처럼 쓸 수 있습니다. 러스트에서 코득 조직화에 필요로하는 모듈 시스템에는 다음과 같은 기능들이 있습니다. 패키지 : 크레이트를 빌드, 테스트, 공유하는 데 사용하는 카고 기능 크레이트 : 라이브러리나 실행 가능한 모듈로 구성된 트리 구조 모듈과 use : organization, scope를 제어하고, 조직 세부 경로를 감추는 데 사용 경로 : 구조체, 함수, 모듈 등의 이름을 지정 - 크레이트(crate) : 러스트가 컴파일 한 차례에 고려하는 가장 작은 코드 단위입니다. 크레이트는 여러..

[Rust] 2023.08.11

[Rust] 열거형(enum)

열거형은 코드에서 다음과 같이 정의할 수 있습니다. enum ItemType { None, Food, Book, } None, Food, Book처럼 열거된 것들을 열거형의 variants라 부릅니다. 열거형의 variants에 대한 인스턴스를 만드는 방법은 다음과 같습니다. let food = ItemType::Food; let book = ItemType::Book; 지난 챕터에 배운 struct에 열거형을 다음과 같이 사용할 수 있는데요, struct Item{ itemType: ItemType, name: String, } let pizza = Item { itemType: ItemType::Food, name: String::from("pizza"); } 위와 같이 struct를 사용하지 않고,..

[Rust] 2023.08.01

[Rust] 구조체 - 메서드

메서드(method)는 함수와 유사하지만, 구조체의 내용 안에 정의되어야 합니다. 메서드의 첫번째 매개변수는 항상 self여야 하며, 메서드가 호출되는 구조체의 인스턴스를 나타냅니다. 따라서 타입을 정의하지 않아도 됩니다. 구조체의 소유권을 가져오지 않고 싶다면 &self를 사용해줍니다. self는 예약어로, 다른 이름을 매개변수에 입력할 경우 타입이 없다는 에러를 출력합니다. impl 블록에서 정의해야 합니다. #[derive(Debug)] struct Rectangle { length : u32, width: u32 } impl Rectangle { fn area(&self) -> u32 { self.length * self.width } } fn struct2() { let rect1 = Recta..

[Rust] 2023.07.30

[Rust] 데이터 구조체

다른 타입의 여러 값을 가질 수 있다는 점에서 튜플과 비슷하지만, 각각을 필드에 정의하고 명명할 수 있다는 점에서 차이가 있습니다. struct를 사용해 다음과 같이 정의하여 사용할 수 있습니다. 인스턴스인 my_data를 생성할 때 값을 입력하는 순서는 중요하지 않지만, 모든 필드에 값을 입력해주어야 합니다. struct UserData { username: String, email: String, sign_in_count: u64, active: bool, } let my_data = UserData { username : String::from("Geukggom"), email : String::from("geukggom@gmail.com"), sign_in_count : 1, active : tr..

[Rust] 2023.07.29
반응형