23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
마지막 8주차 스터디는 7월 29일에 진행 했습니다.
원래 한 주 일찍 하려고 했던 스터디는 제가 코로나에 걸리는 바람에 한 주 미뤄지게되어, 7월 29일에 진행 했습니다.
마지막 챕터는 러스트의 고급 기능들 입니다.
러스트의 가장 장점은 안전성인것에 반해,
고급기능에 unsafe가 있다는건 조금 이상하긴 하지만 컴파일러가 모든 경우의 수를 다 계산하여 검증 해 줄 수 없기 때문에,
어느 정도는 개발자에게 맡기는 방법도 사용하는 것 같습니다.
고급기능을 마지막으로 러스트 프로그래밍 공식가이드 2판 책으로 시작한 스터디는 마무리 했습니다.
공식가이드인 만큼 처음 러스트를 접하는 사람들을 위한 것인지 쉽게 쓰여져 있긴 했지만, 그만큼 조금 더 설명 해야 했을 부분을 대충 넘어가서 살짝 아쉬운 점도 있긴 했습니다.
3개월이라는 시간동안 스터디를 함께 참여해 주시고 공유해주신 스터디원 분들께 모두 감사드립니다.
다음은 19장 고급 기능에 대한 정리 입니다.
러스트는 안전성과 성능을 모두 제공하는 프로그래밍 언어로, 고급 기능을 통해 더욱 유연하고 강력한 코드를 작성할 수 있습니다.
이번 글에서는 안전하지 않은 러스트, 고급 트레이트, 고급 타입, 고급 함수와 클로저, 그리고 매크로에 대해 알아보겠습니다.
러스트의 강력한 안전성 보장에도 불구하고, 때로는 더 낮은 수준의 제어가 필요할 때가 있습니다.
이때 사용하는 것이 바로 "안전하지 않은"(unsafe) 러스트입니다. unsafe 키워드는 러스트의 안전성 검사를 일시적으로 비활성화하여 더 강력한 제어를 가능하게 합니다.
unsafe 블록unsafe 블록을 사용하면 여러 가지 작업을 수행할 수 있습니다.
fn main() {
let mut num = 5;
let r1 = &num as *const i32;
let r2 = &mut num as *mut i32;
unsafe {
println!("r1: {}", *r1);
println!("r2: {}", *r2);
}
}위 예제에서 as *const i32와 as *mut i32는 각각 불변 및 가변 원시 포인터를 생성합니다.
unsafe 블록 내에서만 이러한 포인터를 역참조할 수 있습니다.
unsafe 함수unsafe 함수는 호출자가 함수의 계약을 준수해야 하는 함수입니다.
rust코드 복사
unsafe fn dangerous() {}
fn main() {
unsafe {
dangerous();
}
}위 예제에서 dangerous 함수는 unsafe로 선언되었으며, unsafe 블록 내에서만 호출할 수 있습니다.
고급 트레이트 기능을 사용하면 더욱 유연하고 강력한 인터페이스를 정의할 수 있습니다.
연관 타입은 트레이트 내에서 타입 매개변수를 정의하는 기능입니다.
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}위 예제에서 Item은 Iterator 트레이트의 연관 타입입니다. 이를 통해 제네릭 매개변수의 복잡성을 줄일 수 있습니다.
트레이트 메서드에 기본 구현을 제공할 수 있습니다.
trait Greet {
fn greet(&self) {
println!("Hello!");
}
}
struct Person;
impl Greet for Person {}
fn main() {
let person = Person;
person.greet();
}위 예제에서 Greet 트레이트는 greet 메서드의 기본 구현을 제공합니다. Person 구조체는 이를 구현하지 않고도 사용할 수 있습니다.
러스트는 고급 타입 기능을 제공하여 더 정교한 타입 시스템을 구현할 수 있습니다.
타입 별칭을 사용하면 긴 타입 이름을 더 짧게 만들 수 있습니다.
type Kilometers = i32;
fn main() {
let x: Kilometers = 5;
println!("x is {} kilometers", x);
}위 예제에서 Kilometers는 i32의 별칭입니다. 이를 통해 코드의 가독성을 높일 수 있습니다.
뉴타입 패턴은 튜플 구조체를 사용하여 기존 타입을 감싸는 방법입니다.
struct Meters(i32);
fn main() {
let distance = Meters(5);
println!("Distance is {} meters", distance.0);
}위 예제에서 Meters는 i32를 감싸는 튜플 구조체입니다. 이를 통해 타입 안전성을 높일 수 있습니다.
러스트의 고급 함수와 클로저 기능을 사용하면 더욱 유연한 함수를 작성할 수 있습니다.
고차 함수는 다른 함수를 인수로 받거나 결과로 반환하는 함수입니다.
fn apply<F>(f: F) where F: FnOnce() {
f();
}
fn main() {
let greeting = || println!("Hello!");
apply(greeting);
}위 예제에서 apply 함수는 클로저를 인수로 받아 실행합니다. FnOnce 트레이트를 사용하여 클로저를 제한합니다.
러스트는 클로저의 매개변수와 반환 타입을 자동으로 추론합니다.
fn main() {
let add_one = |x| x + 1;
println!("2 + 1 = {}", add_one(2));
}위 예제에서 클로저 add_one은 매개변수 x와 반환 타입을 자동으로 추론합니다.
매크로는 코드를 생성하는 강력한 도구입니다. 러스트는 선언적 매크로와 프로시저 매크로를 지원합니다.
선언적 매크로는 매크로 규칙을 사용하여 코드를 생성합니다.
macro_rules! say_hello {
() => {
println!("Hello!");
};
}
fn main() {
say_hello!();
}위 예제에서 macro_rules!를 사용하여 say_hello 매크로를 정의합니다. 이를 통해 반복적인 코드를 줄일 수 있습니다.
프로시저 매크로는 함수처럼 작동하며, 입력 토큰 스트림을 받아 출력 토큰 스트림을 반환합니다. 세 가지 종류가 있습니다: 함수 매크로, 파생 매크로, 속성 매크로.
use proc_macro::TokenStream;
#[proc_macro]
pub fn my_macro(input: TokenStream) -> TokenStream {
input
}use proc_macro::TokenStream;
#[proc_macro_derive(MyTrait)]
pub fn my_trait_derive(input: TokenStream) -> TokenStream {
input
}use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn my_attribute(attr: TokenStream, item: TokenStream) -> TokenStream {
item
}러스트의 고급 기능은 언어의 강력함과 유연성을 더욱 확장해줍니다.
unsafe 블록과 함수는 더 낮은 수준의 제어를 가능하게 하고, 고급 트레이트와 타입을 사용하여 더욱 정교한 인터페이스와 타입 시스템을 구현할 수 있습니다.
고급 함수와 클로저는 유연한 함수 작성에 도움을 주며, 매크로는 코드 생성을 통해 반복 작업을 줄여줍니다.
이러한 고급 기능들을 잘 활용하면 러스트 프로그램을 더욱 효율적이고 강력하게 작성할 수 있습니다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.