10분만에 공부해보는 러스트 언어
let x;
x = 42
is equal to
let x = 42;
let x: i32; # i32 : 부호가 있는 32비트 정수, 마치 java의 int와 같은 느낌.
x = 42
let x: i32 = 42;
rust에서는 타입을 명시하지 않을 경우, 기본값으로 i32를 선언한다.
let x;
foobar(x);
x = 42;
it leads to runtime error. so, you have to initialize variables before access.
let x;
x = 42;
foobar(x)
let _ = 42; # this does nothing because 42 is a constant
let _ = get_thing(); # this calls get_thing but throws away its result
let pair = ('a', 17);
pair.0; // this is 'a'
pair.1; // this is 17
let pair: (char, i32) = ('a', 17)
rust에서는 보통 사용 중인 타입에 대해 잘 추론하기 때문에 명확히 지정해줘야 하는 경우는 드물다.
let (some_char, some_int) = ('a', 17);
assert!(some_char, 'a');
assert!(some_int, 17);
let (l, r) = slice.split_at(middle);
let (_, right) = slice.split_at(middle); # 오른쪽 부분만 가져오는 식
let x = vec![1,2,3,4,5,6,7,8]
.iter()
.map(|x| x + 3)
.fold(0, |x, y| x + y);
위 예시처럼 span될 수도 있다.
# void fn
fn greet() {
println!("Hi there!");
}
# integer returning fn
fn fair_dice_roll() -> i32 {
4
}
let x = {
let y = 1;
let z = 2;
y + z // ths is the 'tail'
}
fn fair_dice_roll() -> i32 {
match feeling_lucky {
true => 6,
false => 4,
}
}
반드시 전부 일치해야 한다.
fn print_number(n: number) {
match n.value { //아래처럼 deeply nested 구조도 가능.
1 => println!("one"),
2 => println!("two"),
_ => println!("{}", n.value), // _는 패턴 상관 안쓴다는 뜻.
}
}
let least = std::cmp::min(3, 8);use std::cmp::min;
let least = min(7,1);
rust는 엄격한 범위 규칙이 있기 때문에, 소스 코드에서 볼 수 없는 경우 사용할 수 없다.
type도 name space이다.
let x = "amos".len(); // 4
let x = str::len("amos"); // also 4
struct Number {
odd: bool,
value: i32,
}
they can be initialised using literals:
let x = Number { odd: false, value: 2 };
let y = Number { value: 3, odd: true };
// 즉, 순서는 중요치 않다.
struct Number {
odd: bool,
value: i32,
}
impl Number {
fn is_positive(self) -> bool {
self.value > 0
}
}
let minus_two = Number {
odd: false,
value: -2,
}
println!("{}", minus_two.is_positive());
struct는 JAVA의 클래스와 같은 역할이구나.
위 예시에서 Number가 클래스이며, 해당 속성들 내에서 상속받는 느낌.
! 기본적으로 불변이기때문에 내부 변경 불가
let n = Number { odd: true, value: 17, }; n.odd = false;=> error: cannot assign to 'n.odd', as 'n' is not declared to be mutable.
let mut n = Number {
odd: true,
value: 17,
}
n.value = 19 // all good.
프로그래밍에서 제네릭(Generic) 문법에서 사용되는 형식 매개 변수(Type Parameter)로, 특정 데이터 타입을 '일반화'하여 코드의 재사용성과 유연성을 높이는 데 사용됩니다. T는 Type의 약자이며, 이 변수를 통해 클래스나 메서드가 어떤 특정 타입의 데이터를 다룰지 외부에서 지정할 수 있도록 합니다.
- 타입 일반화:
다양한 데이터 타입에 대해 동일한 기능을 수행하는 클래스나 메서드를 만들 수 있습니다. 예를 들어, 특정 타입을 지정하는 대신 다양한 타입의 객체를 저장할 수 있는 '박스' 클래스를 만들 수 있습니다.- 재사용성과 유연성:
코드를 간결하게 하고 재사용성을 높여줍니다. 각 타입마다 다른 버전을 만들 필요 없이, 단일 제네릭 클래스 또는 메서드를 통해 여러 데이터 형식을 처리할 수 있습니다.- 타입 안정성 증가:
컴파일 시점에 타입 체크가 이루어져, 런타임 시 발생할 수 있는 형변환 오류를 줄여줍니다.- 개발 생산성 향상:
IDE가 해당 객체의 타입을 인지하기 때문에 자동 완성 기능 등을 통해 개발 생산성을 높여줍니다.- 용도 예시
(1) 제네릭 클래스:
클래스 이름 뒤에 < T >를 붙여 해당 클래스가 특정 타입을 일반화된 T로 다룬다는 것을 명시합니다.
(2) 제네릭 메서드:
메서드 자체에 < T >를 선언하여 해당 메서드가 특정 타입의 데이터를 다룰 수 있도록 합니다.- 다른 제네릭 타입 매개 변수
T는 가장 흔하게 사용되는 약자이지만, K(Key), V(Value), E(Element) 등 다른 약자를 사용하여 각자의 의미를 부여하기도 합니다.
struct Pair<T> {
a: T,
b: T,
}
let p1 = Pair { a: 3, b: 9 }; // = Pair<i32>
let p2 = Pair { a: true, b: false }; // = Pair<bool>
fn main() {
let v1 = vec![1,2,3];
let v2 = vec![true, false, true];
}
enum Result<T, E> {
0k(T),
Err(E),
}
les s = str::from_utf8(&[195, 40])
.expect("valid utf-8");
-> error 발생시
thread 'main' panicked at 'valid utf-8:
'Utf8Error{ valid_up_to: 0, error_len: Some(1) }''
let melon = &[240, 159, 141, 137];
match str::from_utf8(melon) {
ok(s) => println!("{}", s),
Err(e) => panic!(e),
}
if let ok(s) = str::from_utf8(melon) {
println!("{}", s),
match std::str::from_utf8(melon) {
ok(s) => println!("{}", s),
Err(e) => return Err(e),
}
ok(()) // (assuming inside 'fn -> Result<(), std::str::Utf8Error>')
let s = str::from_utf8(melon)?;
let natual_numbers = 1..; // 무한대까지 간다.arrange 사용하는 경우
// 0 or greater
(0..).contains(&100); // true
// 20 or less than 20
(..=20).contains(&20)); // true
// only 3, 4, 5
(3..6).contains(&4)); // true
반복 가능한 모든 게 for loop에 사용될 수 있다.
fn main() {
for i in vec![52,49,21] { // vec도 가능
println!("I like number {}", i); // I like number 52 / ~ 49 / ~ 21
}
for i in &[52, 49, 21] { // slice도 가능
println!("I like number {}", i); // I like number 52 / ~ 49 / ~ 21
}
for c in "rust".cahrs() {
println!("get {}", c); // get r / get u / get s / get t
}
}
fn main() {
for c in "SuPRISE INbOUND".chars()
.filter(|C| c.is_lowercase())
.flat_map(|c| c.to_uppercase()) {
print!("{}", c); // output: UB
}
}