■ struct 키워드를 사용해 튜플 구조체를 만드는 방법을 보여준다. ▶ 예제 코드 (RS)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
fn main() { struct Color(i32, i32, i32); struct Point(i32, i32, i32); let black : Color = Color(30, 20, 10); let origin : Point = Point(10, 20, 30); println!("{}, {}, {}", black.0 , black.1 , black.2 ); println!("{}, {}, {}", origin.0, origin.1, origin.2); } /* 30, 20, 10 10, 20, 30 */ |
■ Iterator 트레잇의 rev 메소드를 사용해 반복자 방향을 반대로 하는 방법을 보여준다. ▶ 예제 코드 (RS)
|
for index in (1..11).rev() { println!("{}", index); } |
■ ThreadRng 구조체의 gen_range 메소드를 사용해 임의의 난수를 생성하고 숫자를 맞추는 게임을 만드는 방법을 보여준다. ▶ Cargo.toml
|
[package] name = "test_project" version = "0.1.0" edition = "2021" [dependencies] rand = "0.8.0" |
▶ src/main.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
use std::cmp; use std::io; use rand; use rand::rngs; use rand::Rng; fn main() { println!("Guess the number!"); let mut thread_rng: rngs::ThreadRng = rand::thread_rng(); let secret_number : u32 = thread_rng.gen_range(1..=100); loop { println!("Please input your guess."); let mut guess_string : String = String::new(); io::stdin().read_line(&mut guess_string).expect("Failed to read line"); let guess_number : u32 = match guess_string.trim().parse() { Ok(number) => number, Err(_) => continue }; println!("You guessed : {}", guess_number); match guess_number.cmp(&secret_number) { cmp::Ordering::Less => println!("Too small!"), cmp::Ordering::Greater => println!("Too big!"), cmp::Ordering::Equal => { println!("You win!"); break; } } } } |
test_project.zip
■ 튜플에서 구조 해체를 사용하는 방법을 보여준다. ▶ 예제 코드 (RS)
|
let tuple : (i32, f64, i32) = (500, 6.4, 1); let (x, y, z) = tuple; println!("{}, {}, {}", x, y, z); |
■ Ord 트레잇의 cmp 메소드를 사용해 숫자를 비교하는 방법을 보여준다. ▶ 예제 코드 (RS)
|
use std::cmp; let a : u32 = 10; let b : u32 = 20; match a.cmp(&b) { cmp::Ordering::Less => println!("A가 B보다 작다."), cmp::Ordering::Greater => println!("A가 B보다 크다."), cmp::Ordering::Equal => println!("A와 B가 같다.") } |
■ cargo new 명령을 사용해 프로젝트를 생성하는 방법을 보여준다. 1. [명령 프롬프트]를 실행한다. 2. [명령 프롬프트]에서 아래 명령을 실행한다. ▶ 실행 명령
더 읽기
■ ThreadRng 구조체의 gen_range 메소드를 사용해 임의의 난수를 구하는 방법을 보여준다. ▶ 예제 코드 (RS)
|
use rand::rngs; use rand::Rng; let mut thread_rng : rngs::ThreadRng = rand::thread_rng(); let secret_number : u32 = thread_rng.gen_range(1..=100); |
■ Iterator 트레잇의 map 메소드를 사용해 분할 문자열 벡터를 구하는 방법을 보여준다. ▶ 예제 코드 (RS)
|
use std::str; let source : &str = "가가가,나나나,다다다"; let split :str::Split<'_, &str> = source.split(","); let string_vector : Vec<String> = split.map(|s| s.to_string()).collect(); println!("{:?}", string_vector); |
■ &str 타입의 split 메소드를 사용해 분할 문자열 벡터를 구하는 방법을 보여준다. ▶ 예제 코드 (RS)
|
let source : &str = "가가가,나나나,다다다"; let mut string_vector : Vec<String> = vec![]; for line in source.split(",") { string_vector.push(line.to_string()); } println!("{:?}", string_vector); |
■ AES 암호화 도구를 만드는 방법을 보여준다. ▶ Cargo.toml
|
[package] name = "test_project" version = "0.1.0" edition = "2021" [dependencies] aes = "0.7.5" block-modes = "0.8.1" base64 = "0.13.0" sha2 = "0.9.8" getrandom = "0.2.3" |
▶ src/cipher.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
use aes; use block_modes; use block_modes::block_padding; use block_modes::BlockMode; use sha2; use sha2::Digest; type AesCbc = block_modes::Cbc<aes::Aes256, block_padding::Pkcs7>; const SALT : &str = "LFsMH#kL!IfY:dcEz9F/dvj17nUN"; pub fn encrypt(plain_text : &str, password : &str, initial_value_byte_vector : &Vec<u8>) -> String { let key_byte_vector : Vec<u8> = get_key_byte_vector(password); let cbc : block_modes::Cbc<aes::Aes256, block_padding::Pkcs7> = AesCbc::new_from_slices(&key_byte_vector, &initial_value_byte_vector).unwrap(); let encrypted_byte_vector : Vec<u8> = cbc.encrypt_vec(plain_text.as_bytes()); let encrypted_text : String = base64::encode(encrypted_byte_vector); return encrypted_text; } pub fn decrypt(encrypted_text : &str, password : &str, initial_value_byte_vector : &Vec<u8>) -> String { let key_byte_vector : Vec<u8> = get_key_byte_vector(password); let encrypted_byte_vector : Vec<u8> = base64::decode(encrypted_text).unwrap(); let cbc : block_modes::Cbc<aes::Aes256, block_padding::Pkcs7> = AesCbc::new_from_slices(&key_byte_vector, initial_value_byte_vector).unwrap(); let plain_byte_vector : Vec<u8> = cbc.decrypt_vec(&encrypted_byte_vector).unwrap(); return String::from_utf8(plain_byte_vector).unwrap(); } fn get_key_byte_vector(password : &str) -> Vec<u8> { let password_salt : String = format!("{}::{}", password, SALT); let mut sha256 : sha2::Sha256 = sha2::Sha256::new(); sha256.update(password_salt.as_bytes()); return sha256.finalize().to_vec(); } pub fn get_initial_value_byte_vector() -> Vec<u8> { let mut initial_value_byte_vector : Vec<u8> = vec! [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; getrandom::getrandom(&mut initial_value_byte_vector).unwrap(); return initial_value_byte_vector; } |
▶ src/main.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
use std::env; mod cipher; fn main() { let argument_vector : Vec<String> = env::args().collect(); if argument_vector.len() < 4 { print_usage_message(); return; } let method : String = String::from(argument_vector[1].trim()); let password : String = String::from(argument_vector[2].trim()); let source : String = String::from(argument_vector[3].trim()); let initial_value_byte_vector : Vec<u8> = cipher::get_initial_value_byte_vector(); let target : String = match &method[..] { "enc" => cipher::encrypt(&source, &password, &initial_value_byte_vector), "dec" => cipher::decrypt(&source, &password, &initial_value_byte_vector), _ => { print_usage_message(); return; } }; println!("{}", target); } fn print_usage_message() { println!("[USAGE] test_project (enc|dec) password source"); } |
test_project.zip
■ getrandom 크레이트를 설치하는 방법을 보여준다. ▶ Cargo.toml
|
... [dependencies] getrandom = "0.2.3" |
■ sha2 크레이트를 설치하는 방법을 보여준다. ▶ Cargo.toml
|
... [dependencies] sha2 = "0.9.8" |
■ block-modes 크레이트를 설치하는 방법을 보여준다. ▶ Cargo.toml
|
... [dependencies] block-modes = "0.8.1" |
■ base64 크레이트를 설치하는 방법을 보여준다. ▶ Cargo.toml
|
... [dependencies] base64 = "0.13.0" |
■ aes 크레이트를 설치하는 방법을 보여준다. ▶ Cargo.toml
|
... [dependencies] aes = "0.7.5" |
■ get 함수를 사용해 이미지 파일을 다운로드하는 방법을 보여준다. ▶ Cargo.toml
|
[package] name = "test_project" version = "0.1.0" edition = "2021" [dependencies] tokio = { version = "1", features = ["full"] } reqwest = "0.11.4" |
▶ src/main.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
use std::fs; use std::io::Write; #[tokio::main] async fn main() { let source_url : &str = "https://blog.kakaocdn.net/dn/bcZgvb/btskiAmI1cg/pm8rWnRjBTkMnvYcxNDgDk/img.png"; let target_bytes = reqwest::get(source_url).await.unwrap().bytes().await.unwrap(); let target_file_path : &str = "download.png"; let mut file : fs::File = fs::File::create(target_file_path).unwrap(); file.write_all(&target_bytes).unwrap(); } |
test_project.zip
■ HTML 문자열을 파싱하는 방법을 보여준다. ▶ Cargo.toml
|
[package] name = "test_project" version = "0.1.0" edition = "2021" [dependencies] scraper = "0.12" |
▶ src/main.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
use scraper; fn main() { let html_string : &str = "<html><body><p>테스트 문자열 1</p><p>테스트 문자열 1</p></body></html>"; let html : scraper::Html = scraper::Html::parse_document(&html_string); let selector : scraper::Selector = scraper::Selector::parse("p").unwrap(); for (index, element) in html.select(&selector).enumerate() { println!("{} : {:?}", index, element.value()); } } |
test_project.zip
■ get 함수를 사용해 웹 페이지를 다운로드하는 방법을 보여준다. ▶ Cargo.toml
|
[package] name = "test_project" version = "0.1.0" edition = "2021" [dependencies] tokio = { version = "1", features = ["full"] } reqwest = "0.11.4" |
▶ src/main.rs
|
#[tokio::main] async fn main() { let html : String = reqwest::get("https://icodebroker.tistory.com") .await.unwrap() .text().await.unwrap(); println!("{}", html); } |
test_project.zip
■ encode 함수를 사용해 URL 인코딩 문자열을 구하는 방법을 보여준다 ▶ 예제 코드 (RS)
|
use std::borrow; let url_encoded_cow : borrow::Cow<'_, str> = urlencoding::encode("테스트 1234"); println!("{}", url_encoded_cow); /* %ED%85%8C%EC%8A%A4%ED%8A%B8%201234 */ |
■ 웹 사이트에서 이미지 파일을 다운로드하는 방법을 보여준다. ▶ Cargo.toml
|
[package] name = "test_project" version = "0.1.0" edition = "2021" [dependencies] tokio = { version = "1", features = ["full"] } reqwest = "0.11.4" scraper = "0.12" urlencoding = "2.1" |
▶ src/main.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
use std::fs; use std::io::Write; use scraper; use tokio::time; #[tokio::main] async fn main() { for title in ["test", "yiy"] { download_images_async(title).await; } } async fn download_images_async(title : &str) { let root_url : &str = "https://uta.pw/shodou"; let url : String = format! ( "{}/index.php?titles&show&title={}", root_url, urlencoding::encode(title) ); println!("GET : {}", url); let html_string : String = reqwest::get(url).await.unwrap().text().await.unwrap(); let html : scraper::Html = scraper::Html::parse_document(&html_string); let selector : scraper::Selector = scraper::Selector::parse(".articles img").unwrap(); for(index, element) in html.select(&selector).enumerate() { let source : &str = element.value().attr("src").unwrap(); let img_url : String = format!("{}/{}", root_url, source); println!("{}", img_url); let file_name : String = format!("{}_{}.png", title, index); let bytes = reqwest::get(img_url).await.unwrap().bytes().await.unwrap(); let mut file : fs::File = fs::File::create(file_name).unwrap(); file.write_all(&bytes).unwrap(); time::sleep(time::Duration::from_millis(1000)).await; } } |
test_project.zip
■ Duration 구조체의 from_millis 연관 함수를 사용해 밀리초 단위 Duration 객체를 구하는 방법을 보여준다. ▶ 예제 코드 (RS)
|
use tokio::time; let duration : time::Duration = time::Duration::from_millis(1000); |
■ urlencoding 크레이트를 설치하는 방법을 보여준다. ▶ Cargo.toml
|
... [dependencies] urlencoding = "2.1" |
■ scraper 크레이트를 설치하는 방법을 보여준다. ▶ Cargo.toml
|
... [dependencies] scraper = "0.12" |
■ join! 매크로를 사용해 비동기 병렬 처리 완료시까지 대기하는 방법을 보여준다. ▶ Cargo.toml
|
[package] name = "test_project" version = "0.1.0" edition = "2021" [dependencies] tokio = { version = "1", features = ["full"] } |
▶ src/main.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
use tokio::time; async fn print_message_async(second_count : u64, message : &str) { time::sleep(time::Duration::from_secs(second_count)).await; println!("{} : {}", second_count, message); } #[tokio::main] async fn main() { tokio::spawn(print_message_async(3, "메시지 #1")); tokio::spawn(print_message_async(2, "메시지 #2")); tokio::spawn(print_message_async(1, "메시지 #3")); time::sleep(time::Duration::from_secs(4)).await; println!("------------"); tokio::join! ( print_message_async(2, "메시지 #4"), print_message_async(3, "메시지 #5"), print_message_async(1, "메시지 #6") ); } |
test_project.zip
■ reqwest 크레이트를 설치하는 방법을 보여준다. ▶ Cargo.toml
|
... [dependencies] reqwest = "0.11.4" |