😪
Rustで初学者がつまづいたところメモ
unwrap
impl<T, E> Result<T, E> {
/// ```should_panic
/// let x: Result<u32, &str> = Err("emergency failure");
/// x.unwrap(); // panics with `emergency failure`
/// ```
#[inline]
#[track_caller]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn unwrap(self) -> T
where
E: fmt::Debug,
{
match self {
Ok(t) => t,
Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", &e),
}
}
prelude
importを一辺に行ってくれる仕組みらしい.
Arc: Atomically Reference Counted
Trait
RustのTraitは
mixinではない → 継承できる & 多重継承を単一継承に変換できないから
interfaceではない → メソッドに具体的な実装を持たせることができるから
derive macro
#[derive(Debug, Error, Clone, Copy)]
pub struct ValidatedRequest<T>(pub T);
型(或いは構造体)に対してTraitを実装する機能.
上記の例では、Debugトレイトに実装してあるメソッドが、ValidateRequest構造体にも実装される.
async-trait
RustはTraitのメソッドをasyncにできないので、それを解決するパッケージ(Trait).
#[async_trait]
impl<T, S, B> FromRequest<S, B> for ValidatedRequest<T>
where
T: DeserializeOwned + Validate,
S: Send + Sync,
B: HttpBody + Send + 'static,
B::Data: Send,
B::Error: Into<BoxError>,
{
custom attribute macro
独自のattributeを定義することができる.
#[proc_macro_attribute]
pub fn async_trait(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as Args);
let mut item = parse_macro_input!(input as Item);
expand(&mut item, args.local);
TokenStream::from(quote!(#item))
}
あとで読む
impl<T> MyTrait for MyStruct<T>
ValidatedRequestはジェネリクスであり、実装の中でジェネリクスを使う必要があるので impl<T, S>
と宣言している
#[async_trait]
impl<T, S> FromRequest<S> for ValidatedRequest<T>
.map(|x| x + 1)
関数の引数として渡すことのできる名前のない関数(無名関数)のこと
pythonで言うところのlambda x: x + 1
Discussion