- 발표: 유병조
- 발표: 정연집
- 발표: 김기덕
- 발표: 이재현
- 러스트에는 복구 가능한(recoverable) 에러와 복구 불가능한(unrecoverable)에러가 있음.
- 복구 불가능한 오류가 발생했을 때 실행을 멈추는 panic!
- 되감기 없이 프로그램 끝내는 대안: 'abort'(Cargo.Toml을 통해 설정)
- 유효하지 않은 인덱스 접근(buffer overread)
let v = vec![1, 2, 3];
v[99];
- RUST_BACKTRACE 환경변수를 설정하여 사용.
$ RUST_BACKTRACE=1 cargo run
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => {
panic!("There was a problem opening the file: {:?}", error)
},
};
}
use std::fs::File;
use std::io::ErrorKind;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(ref error) if error.kind() == ErrorKind::NotFound => {
match File::create("hello.txt") {
Ok(fc) => fc,
Err(e) => {
panic!(
"Tried to create file but there was a problem: {:?}",
e
)
},
}
},
Err(error) => {
panic!(
"There was a problem opening the file: {:?}",
error
)
},
};
}
if error.kind() == ErrorKind::NotFound
- 매치 가드(match guard) 라고 부름.
- unwrap
use std::fs::File;
fn main() {
let f = File::open("hello.txt").unwrap();
}
Result
값이Ok
라면 값 반환하고Err
라면panic!
- expect
use std::fs::File;
fn main() {
let f = File::open("hello.txt").expect("Failed to open hello.txt");
}
unwrap
과 유사하지만Err
이면panic!
과 함께 에러 메시지를 담을 수 있음.
use std::io;
use std::io::Read;
use std::fs::File;
fn read_username_from_file() -> Result<String, io::Error> {
let f = File::open("hello.txt");
let mut f = match f {
Ok(file) => file,
Err(e) => return Err(e),
};
let mut s = String::new();
match f.read_to_string(&mut s) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
use std::io;
use std::io::Read;
use std::fs::File;
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = File::open("hello.txt")?;
let mut s = String::new();
// Err 시 from 함수를 통해 에러 타입 변환 후 반환.
f.read_to_string(&mut s)?;
Ok(s)
}
- match와 '?'의 차이
- match: 함수 반환값에 맞춰 코드를 작성해주어야함.
- '?': 함수의 정의된 반환값으로 자동 반환.
use std::fs::File;
fn main() {
let f = File::open("hello.txt")?;
}
- main 함수는 반환 타입이
()
이므로 컴파일 에러 발생함.
use std::net::IpAddr;
let home = "127.0.0.1".parse::<IpAddr>().unwrap();
- 위와 같이
Err
variant가 절대 발생하지 않는다는 것을 확신할 수 있을 때만unwrap
사용 권장.
- 발표: 이명수
- generic을 사용하여 중복된 코드를 합칠 수 있다.
- C++의 템플릿과 유사
fn largest<T>(list: &[T]) -> T {
- 제네릭은 컴파일 타임에 타입이 정해지기때문에 성능 상 별 차이가 없다.
- 다른 언어의 interface와 유사
pub trait Summarizable {
fn summary(&self) -> String;
}
- 오버라이딩된 구현으로부터 기본 구현을 호출하는 것은 불가능하다는 점을 기억해주세요.
- 제네릭 타입에 제약을 가해서 이 제네릭 타입에 따라 특정 트레잇을 구현해 필요한 동작을 수행할 수 있도록 해줄 수 있다.
-
러스트에서 모든 참조자는 라이프타임(lifetime) 을 갖는데, 이는 해당 참조자가 유효한 스코프입니다.
-
라이프타임의 주목적은 댕글링 참조자(dangling reference)를 방지하는 것.
&i32 // a reference
&'a i32 // a reference with an explicit lifetime
&'a mut i32 // a mutable reference with an explicit lifetime
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
1. 참조자인 각각의 파라미터는 고유한 라이프타임 파라미터를 갖습니다. 바꿔 말하면, 하나의 파라미터를 갖는 함수는 하나의 라이프타임 파라미터를 갖고: fn foo<'a>(x: &'a i32), 두 개의 파라미터를 갖는 함수는 두 개의 라이프타임 파라미터를 따로 갖고: fn foo<'a, 'b>(x: &'a i32, y: &'b i32), 이와 같은 식입니다.
2. 만일 정확히 딱 하나의 라이프타임 파라미터만 있다면, 그 라이프타임이 모든 출력 라이프타임 파라미터들에 대입됩니다: fn foo<'a>(x: &'a i32) -> &'a i32.
3. 만일 여러 개의 입력 라이프타임 파라미터가 있는데, 메소드라서 그중 하나가 &self 혹은 &mut self라고 한다면, self의 라이프타임이 모든 출력 라이프타임 파라미터에 대입됩니다. 이는 메소드의 작성을 더욱 멋지게 만들어줍니다.
과제: 첼시를 도와줘! (https://www.acmicpc.net/problem/11098)
- 이지한: 이번에는 과제랑 스터디에 좀 충실하지 못했던 것 같습니다. 다음에는 좀더 열심히 준비해보겠습니다.
- 김기덕: 과제하면서 소유권이나 라이프타임 개념이 함께 적용되다 보니 너무 어려웠습니다...ㅠ
- 유병조: 라이프사이클 개념이 아리까리하네요. 다시 읽어봐야겠어요ㅠ
- 이명수: 자꾸 까먹네요.. 다시 1장부터 봐야겠어요 ㅎㅎ
- 이재현: 라이프사이클을 명시한다는 개념이 잘 와닿지 않아서 힘들었던 것 같네요..
- 정연집: 이번에 과제하면서 전에 했던 개념들을 까먹다 보니 한참헤맸네요..ㅠㅠㅠ
- 허신: 내용 이해가 완전히 되지 않은 상태에서 서기 하려니 너무 힘드네요 ㅠㅠ