Rust(Programming Language)는 Performance, Reliability, Productivity를 목표로 만들어진 개발언어이다. 특히 메모리 안정성에 초점이 맞추어져 있으며 프로그래밍 언어에서 고수준의 인간공학과 저수준의 제어가 조화롭게 구성되어 있다. 또한, 성능 면에서 C++와 비슷한 수준을 목표로 하고 있다. Rust를 학습하는 데 필요한 정보와 Rust만의 특징(References, Ownership, Borrowing, …)이 있는 부분을 기초 예제로 정리하였다.
학습에 필요한 자원
- Rust Tutorial(문서)
- Rust Programming Language(문서)
- Rust Crash Course(Traversy Media, 동영상)
- Rust Tutorial(Derek Banas, 동영상)
- Rust Programming Tutorials(dcode, 동영상)
- Rust Tutorial(Doug Milford, 동영상)
- Rust Programming Language( Knowledge Hub, 동영상)
환경구성
# rustfmt.toml
max_width = 160
fn_args_layout = "Compressed"
use_small_heuristics = "Max"
# Cargo.toml
[dependencies]
serde = "1.0"
serde_json = "1.0"
serde_derive = "1.0"
log = "0.4.8"
simplelog = "^0.7.4"
기초예제 - 1
//Reference
fn main() {
let mut x = 10;
let y = &mut x;
*y += 1;
println!("y is {}", y);
*y += 1;
println!("x is {}", x);
}
//String, str
fn main() {
let mut my_string = String::from("How's it going? My name is MsJ");
println!("Length: {}", my_string.len());
println!("String is empty? {}", my_string.is_empty());
for token in my_string.split_whitespace() {
println!("{}", token);
}
println!("Does the string contain 'MsJ'? {}", my_string.contains("MsJ"));
my_string.push_str(" Welcome to your tutorial on Strings!");
println!("{}", my_string);
// String vs str
let ex_str: &str = "Hello";
let ex_string: String = String::from("World");
println!("{} {}", ex_str, ex_string);
let ex_from_str: String = ex_str.to_string();
let ex_from_str2: String = "World".to_string();
println!("{} {}", ex_from_str, ex_from_str2);
let ex_from_hardcoded = String::from("Some hardcoded");
let ex_from_str_var = String::from(ex_str);
let str_from_string: &str = &ex_str;
println!("{} {} {}", ex_from_hardcoded, ex_from_str_var, str_from_string);
let combine_string_literals = ["first", " ", "second"].concat();
let combine_with_format_macro = format!("{} {}", "first", "second");
let string_plus_str = ex_str.to_string() + "\x20" + &ex_string;
println!("{} {} {}", combine_string_literals, combine_with_format_macro, string_plus_str);
let mut mut_string = String::new();
mut_string.push_str(ex_str);
mut_string.push_str(" 가나닭");
mut_string.push('!');
println!("{}", mut_string);
let a = String::from("a");
let b = String::from("b");
let combined = a + "\x20" + &b + "\x20" + &mut_string;
println!("{}", combined);
let str_from_substring: &str = &ex_str[0..=2];
println!("{}", str_from_substring); //Hel
let char_by_index = &ex_str.chars().nth(0);
println!("{:?}", char_by_index); // Some('H')
println!("{}", char_by_index.iter().cloned().collect::<String>()); //H
match char_by_index {
Some(c) => println!("Found a char {}", c),
None => {}
}
if let Some(c) = ex_str.chars().nth(1) {
println!("Found a char {}", c);
}
}
기초예제 - 2
// struct & impl
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn print_desc(&self) {
println!("Rectangle: {} x {}", self.width, self.height);
}
fn is_square(&self) -> bool {
return self.width == self.height;
}
fn area(&self) -> u32 {
return self.width * self.height;
}
}
struct RectangleRef<'a> {
width: &'a mut u32,
height: &'a mut u32,
}
fn main() {
let mut my_rect = Rectangle { width: 10, height: 5 };
my_rect.print_desc();
println!("Rectangle is a square: {}", my_rect.is_square());
println!("Area : {}", my_rect.area());
my_rect.width = 10;
my_rect.height = 10;
println!("Area : {}", my_rect.area());
let r = RectangleRef { width: &mut my_rect.width, height: &mut my_rect.height };
*r.width = 2;
*r.height = 3;
println!("Area : {}", my_rect.area());
}
// Implementing Traits
struct Person {
name: String,
age: u8,
}
impl ToString for Person {
fn to_string(&self) -> String {
return format!("My name is {} and I am {}", self.name, self.age);
}
}
fn main() {
let msj = Person { name: String::from("MsJ"), age: 30 };
println!("{}", msj.to_string());
}
// Defining Traits
struct Person {
name: String,
age: u8,
}
trait HasVoiceBox {
fn speak(&self);
fn can_speak(&self) -> bool;
}
impl HasVoiceBox for Person {
fn speak(&self) {
println!("Hello, my name is {}", self.name);
}
fn can_speak(&self) -> bool {
if self.age > 0 {
return true;
}
return false;
}
}
fn main() {
let people = Person { name: String::from("MsJ"), age: 30 };
people.speak();
println!("Can {} speak? {}", people.name, people.can_speak());
}
기초예제 - 3
//Log, Parsing JSON
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate log;
extern crate simplelog;
use simplelog::*;
use std::fs::OpenOptions;
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
is_male: bool,
}
fn main() {
let json_str = r#"
{
"name": "MsJ",
"age": 30,
"is_male": true
}
"#;
let file = OpenOptions::new().read(true).write(true).create(true).append(true).open("my_rust_binary.log");
CombinedLogger::init(vec![
TermLogger::new(LevelFilter::Trace, Config::default(), TerminalMode::Mixed).unwrap(),
WriteLogger::new(LevelFilter::Trace, Config::default(), file.unwrap()),
])
.unwrap();
let res = serde_json::from_str(json_str);
debug!("*** json parse - start ***");
if res.is_ok() {
let p: Person = res.unwrap();
println!("The name is {}", p.name);
info!("name : {}", p.name)
} else {
let s = res.err();
println!("Sorry! Could not parse JSON : {:?}", s);
error!("{:?}", s);
}
debug!("*** json parse - end ***");
}