/// `Vec`, . /// /// `vec!` `Vec`s . /// : /// /// - `Vec` : /// /// ``` /// let v = vec![1, 2, 3]; /// assert_eq!(v[0], 1); /// assert_eq!(v[1], 2); /// assert_eq!(v[2], 3); /// ``` /// /// - `Vec` : /// /// ``` /// let v = vec![1; 3]; /// assert_eq!(v, [1, 1, 1]); /// ``` /// /// - , /// `Clone`, , . /// /// `clone()` , /// `Clone`. , /// `vec![Rc::new(1); 5]` integer , /// . #[cfg(not(test))] #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! vec { ($elem:expr; $n:expr) => ( $crate::vec::from_elem($elem, $n) ); ($($x:expr),*) => ( <[_]>::into_vec($crate::boxed::Box::new([$($x),*])) ); ($($x:expr,)*) => (vec![$($x),*]) }
// // T -> T . // // macro_rules! impl_from { ($Small: ty, $Large: ty) => { impl From<$Small> for $Large { fn from(small: $Small) -> $Large { small as $Large } } } } // -> impl_from! { u8, u16 } impl_from! { u8, u32 } impl_from! { u8, u64 } // ...
macro_rules! make_struct { (name: ident) => { struct name { field: u32, } } } make_struct! { Foo }
<anon>:10:16: 10:19 error: no rules expected the token `Foo` <anon>:10 make_struct! { Foo } ^~~ playpen: application terminated with error code 101
struct name { field: u32 }
use std::fs::File; fn main() { let x = try!(File::open("Hello")); }
<std macros>:5:8: 6:42 error: mismatched types: expected `()`, found `core::result::Result<_, _>` (expected (), found enum `core::result::Result`) [E0308] <std macros>:5 return $ crate:: result:: Result:: Err ( <std macros>:6 $ crate:: convert:: From:: from ( err ) ) } } ) <anon>:4:13: 4:38 note: in this expansion of try! (defined in <std macros>) <std macros>:5:8: 6:42 help: see the detailed explanation for E0308
enum IpAddress { V4(IPv4Address), V6(Ipv6Address), } fn connect(addr: IpAddress) { // , , match addr { V4(ip) => connect_v4(ip), V6(ip) => connect_v6(ip), } }
struct MyType { data: u32, } // , trait MyTrait { fn foo(&self) -> u32; } // impl MyTrait for MyType { fn foo(&self) -> u32 { self.data } } fn main() { let mine = MyType { data: 0 }; println!("{}", mine.foo()); }
impl Trait for Type
impl Trait for Box<MyType>
// , . struct Concrete { data: u32, } // . `<..>` . // `Generic` , // `Concrete`, `u32`. struct Generic<T> { data: T, } // impl Concrete { fn new(data: u32) -> Concrete { Concrete { data: data } } fn is_big(&self) -> bool { self.data > 120 } } // Foo. // , , , // // . // ( , - ..) impl Generic<u32> { fn is_big(&self) -> bool { self.data > 120 } } // T. // "impl" Generic. // , // , <T>. impl<T> Generic<T> { fn new(data: T) -> Generic<T> { Generic { data: data } } fn get(&self) -> &T { &self.data } } // . trait Clone { fn clone(&self) -> Self; } // . // . // , . // . trait Equal<T> { fn equal(&self, other: &T) -> bool; } // impl Clone for Concrete { fn clone(&self) -> Self { Concrete { data: self.data } } } // impl Equal<Concrete> for Concrete { fn equal(&self, other: &Concrete) -> bool { self.data == other.data } } // , , ! impl Clone for u32 { fn clone(&self) -> Self { *self } } impl Equal<u32> for u32 { fn equal(&self, other: &u32) -> Self { *self == *other } } // , ! impl Equal<i32> for u32 { fn equal(&self, other: &i32) -> Self { if *other < 0 { false } else { *self == *other as u32 } } } // impl<T: Equal<u32>> Equal<T> for Concrete { fn equal(&self, other: &T) -> bool { other.equal(&self.data) } } // // , , `T` // `Clone`! * * (trait bound). // ( , . - ..) impl<T: Clone> Clone for Generic<T> { fn clone(&self) -> Self { Generic { data: self.data.clone() } } } // . // - U. impl<T: Equal<U>, U> Equal<Generic<U>> for Generic<T> { fn equal(&self, other: &Generic<U>) -> bool { self.equal(&other.data) } } // , . impl Concrete { fn my_equal<T: Equal<u32>>(&self, other: &T) -> bool { other.equal(&self.data) } } impl<T> Generic<T> { // , : `equal` , // , . // (`x == y` `y == x`). , // `T: Equal<U>` ? // `T`, `U` ! // . fn my_equal<U: Equal<T>>(&self, other: &Generic<U>) -> bool { other.data.equal(&self.data) } }
// struct Generic<T> { data: T } impl<T> Generic<T> { fn new(data: T) { Generic { data: data } } } fn main() { let thing1 = Generic::new(0u32); let thing2 = Generic::new(0i32); }
// struct Generic_u32 { data: u32 } impl Generic_u32 { fn new(data: u32) { Generic { data: data } } } struct Generic_i32 { data: i32 } impl Generic_i32 { fn new(data: i32) { Generic { data: data } } } fn main() { let thing1 = Generic_u32::new(0u32); let thing2 = Generic_i32::new(0i32); }
// Vec::new() , // , . . // `Vec`, - . let mut x = Vec::new(); // `u8` `x`, `Vec<T>` x.push(0u8); x.push(10); x.push(20); // `collect` . , // `FromIterator`, Vec VecDeque. // - , // `collect` , `Vec::new()`, // // - . let y: Vec<u8> = x.clone().into_iter().collect(); // , // "-" `::<>`! let y = x.clone().into_iter().collect::<Vec<u8>>();
trait Print { fn print(&self); } impl Print for i32 { fn print(&self) { println!("{}", self); } } impl Print for i64 { fn print(&self) { println!("{}", self); } } fn main() { // let x = 0i32; let y = 10i64; x.print(); // 0 y.print(); // 10 // Box<Print> - -, // , Print. Box<Print> // `Box<T: Print>`, -, `Box<Print>`. // `data` `Box<Print>`, // - ! // , i32 i64 , // . let data: [Box<Print>; 2] = [Box::new(20i32), Box::new(30i64)]; // . for val in &data { val.print(); // 20, 30 } }
trait Clone { fn clone(&self) -> Self; }
fn main() { let x: &Clone = ...; // - , let y = x.clone(); // , ...? }
trait Animal { } // trait Feline { } // trait Pet { } // // , , struct Cat { } // , struct Dog { } // , struct Tiger { }
Cat vtable Dog vtable Tiger vtable + ----------------- + + ----------------- + + ----------- ------ + | type stuff | | type stuff | | type stuff | + ----------------- + + ----------------- + + ----------- ------ + | Animal stuff | | Animal stuff | | Animal stuff | + ----------------- + + ----------------- + + ----------- ------ + | Pet stuff | | Pet stuff | | Feline stuff | + ----------------- + + ----------------- + + ----------- ------ + | Feline stuff | + ----------------- +
Cat vtable Dog vtable Tiger vtable + ----------------- + + ----------------- + + ----------- ------ + | type stuff | | type stuff | | type stuff | + ----------------- + + ----------------- + + ----------- ------ + | Animal stuff | | Animal stuff | | Animal stuff | + ----------------- + + ----------------- + + ----------- ------ + | Feline stuff | | Pet stuff | | Feline stuff | + ----------------- + + ----------------- + + ----------- ------ + | Pet stuff | + ----------------- +
Cat vtable Dog vtable Tiger vtable + ----------------- + + ----------------- + + ----------- ------ + | type stuff | | type stuff | | type stuff | + ----------------- + + ----------------- + + ----------- ------ + | Animal stuff | | Animal stuff | | Animal stuff | + ----------------- + + ----------------- + + ----------- ------ + | Feline stuff | | | | Feline stuff | + ----------------- + + ----------------- + + ----------- ------ + | Pet stuff | | Pet stuff | + ----------------- + + ----------------- +
Cat's Pet vtable Dog's Pet vtable +-----------------+ +-----------------+ | type stuff | | type stuff | +-----------------+ +-----------------+ | Pet stuff | | Pet stuff | +-----------------+ +-----------------+
// ... trait Print { fn print(&self); } impl Print for i32 { fn print(&self) { println!("{}", self); } } impl Print for i64 { fn print(&self) { println!("{}", self); } } // ?Sized , T (&, Box, Rc, ). // Sized ( ) - , . // Traits [T] " ". // `T: ?Sized`, // T , , // Sized . fn print_it_twice<T: ?Sized + Print>(to_print: &T) { to_print.print(); to_print.print(); } fn main() { // : . print_it_twice(&0i32); // 0, 0 print_it_twice(&10i64); // 10, 10 // i32::Print i64::Print. let data: [Box<Print>; 2] = [Box::new(20i32), Box::new(30i64)]; for val in &data { // : . // &Box<Print> &Print , // - ... print_it_twice(&**val); // 20, 20, 30, 30 } }
trait Iterator<T> { fn next(&mut self) -> Option<T>; } /// , , struct StackIter<T> { data: Vec<T>, } // [min, max) struct RangeIter { min: u32, max: u32, } impl<T> Iterator<T> for StackIter<T> { fn next(&mut self) -> Option<T> { self.data.pop() } } impl Iterator<u32> for RangeIter { fn next(&mut self) -> Option<u32> { if self.min >= self.max { None } else { let res = Some(self.min); self.min += 1; res } } }
trait Iterator { // , // type Item; fn next(&mut self) -> Option<Self::Item>; } /// , , struct StackIter<T> { data: Vec<T>, } // [min, max) struct RangeIter { min: u32, max: u32, } impl<T> Iterator for StackIter<T> { // // - type Item = T; fn next(&mut self) -> Option<Self::Item> { self.data.pop() } } impl Iterator for RangeIter { // type Item = u32; fn next(&mut self) -> Option<Self::Item> { if self.min >= self.max { None } else { let res = Some(self.min); self.min += 1; res } } }
impl<T> Iterator for RangeIter { type Item = T; fn next(&mut self) -> Option<Self::Item> { unimplemented!() } }
<anon>:3:6: 3:7 error: the type parameter `T` is not constrained by the impl trait, self type, or predicates [E0207] <anon>:3 impl<T> Iterator for RangeIter { ^
trait StateMachine { type NextState: StateMachine; fn step(self) -> Option<Self::NextState>; }
trait StateMachine<NextStep: StateMachine<_____>> { fn step(self) -> Option<NextState>; }
trait StateMachine { // Box ! self Box<Self>. // Rc<Self> , *Box *. // ( , - ..) fn step(self: Box<Self>) -> Option<Box<StateMachine>>; }
impl<T> Generic<T> { // , : `equal` , // , . // (`x == y` `y == x`). , // `T: Equal<U>` ? // `T`, `U` ! // . fn my_equal<U: Equal<T>>(&self, other: &Generic<U>) -> bool { other.data.equal(&self.data) } }
// : // " ", // , Item! fn min<I: Iterator<Item = T>, T: Ord>(mut iter: I) -> Option<I::Item> { if let Some(first) = iter.next() { let mut min = first; for x in iter { if x < min { min = x; } } Some(min) } else { None } }
impl<T> Generic<T> { fn my_equal<U>(&self, other: &Generic<U>) -> bool where T: Equal<U> { self.data.equal(&other.data) } } fn min<I>(mut iter: I) -> Option<I::Item> where I: Iterator, I::Item: Ord, { if let Some(first) = iter.next() { let mut min = first; for x in iter { if x < min { min = x; } } Some(min) } else { None } }
trait Print { fn print(&self); // `where Self: Sized` , // - . , // Print -! fn copy(&self) -> Self where Self: Sized; } impl Print for u32 { fn print(&self) { println!("{}", self); } fn copy(&self) -> Self { *self } } fn main() { let x: Box<Print> = Box::new(0u32); x.print(); }
let x: Option<u32> = Some(0); let y: Option<bool> = x.map(|v| v > 5);
fn get_first(input: &(u32, i32)) -> &u32 { &input.0 } fn main() { let a = (0, 1); let b = (2, 3); let x = Some(&a); let y = Some(&b); println!("{}", x.map(get_first).unwrap()); println!("{}", y.map(get_first).unwrap()); }
trait MyFn<Input> { type Output; } // -; // , . struct Thunk; impl MyFn<&(u32, i32)> for Thunk { type Output = &u32; }
<anon>:9:11: 9:22 error: missing lifetime specifier [E0106] <anon>:9 impl MyFn<&(u32, i32)> for Thunk { ^~~~~~~~~~~ <anon>:9:11: 9:22 help: see the detailed explanation for E0106 <anon>:10:19: 10:23 error: missing lifetime specifier [E0106] <anon>:10 type Output = &u32; ^~~~ <anon>:10:19: 10:23 help: see the detailed explanation for E0106 error: aborting due to 2 previous errors
fn get_first<'a>(input: &'a (u32, i32)) -> &'a u32 { &input.0 }
trait MyFn<Input> { type Output; } struct Thunk; impl<'a> MyFn<&'a (u32, i32)> for Thunk { type Output = &'a u32; }
/// struct Filter<I, F> { iter: I, pred: F, } /// fn filter<I, F>(iter: I, pred: F) -> Filter<I, F> { Filter { iter: iter, pred: pred } } impl<I, F> Iterator for Filter<I, F> where I: Iterator, F: Fn(&I::Item) -> bool, // ! - ! ? { type Item = I::Item; fn next(&mut self) -> Option<I::Item> { while let Some(val) = self.iter.next() { if (self.pred)(&val) { return Some(val); } } None } } fn main() { let x = vec![1, 2, 3, 4, 5]; for v in filter(x.into_iter(), |v: &i32| *v % 2 == 0) { println!("{}", v); // 2, 4 } }
F: Fn(&I::Item) -> bool
for<'a> F: Fn(&I::Item) -> bool
// , . ! /// . /// RefCount Rc Arc, . struct Node<RefCount: RcLike, T> { elem: T, next: Option<RefCount<Node<RefCount, T>>>, }
/// , `next` , /// . trait RefIterator { type Item; fn next(&mut self) -> &mut T }
trait RefIterator { type Item; fn next<'a>(&'a mut self) -> &'a mut Self::Item; }
trait RefIterator { type Item; fn next<'a>(&'a mut self) -> Self::Item<'a>; }
trait TypeToType<Input> { type Output; }
use std::marker::PhantomData; use std::mem; use std::cmp; // , RefIter struct MyType<'a> { slice: &'a mut [u8], index: usize, } // : trait LifetimeToType<'a> { type Output; } // - , // /// &'* T struct Ref_<T>(PhantomData<T>); /// &'* mut T struct RefMut_<T>(PhantomData<T>); /// MyType<*> struct MyType_; // , impl<'a, T: 'a> LifetimeToType<'a> for Ref_<T> { type Output = &'a T; } impl<'a, T: 'a> LifetimeToType<'a> for RefMut_<T> { type Output = &'a mut T; } impl<'a> LifetimeToType<'a> for MyType_ { type Output = MyType<'a>; } // , ! // `Self::TypeCtor as LifetimeToType<'a>>::Output` // - 'a TypeCtor. // // , : <X as Trait>::AssociatedItem " -", // . // // : , HRTB, // `T: 'a`. // `for<'a> Self::TypeCtor: LifetimeToType<'a>` // `&'a T` `'a`, // `T: 'static`! // "where" `next`. trait RefIterator { type TypeCtor; fn next<'a>(&'a mut self) -> Option<<Self::TypeCtor as LifetimeToType<'a>>::Output> where Self::TypeCtor: LifetimeToType<'a>; } // ! struct Iter<'a, T: 'a> { slice: &'a [T], } struct IterMut<'a, T: 'a> { slice: &'a mut [T], } struct MyIter<'a> { slice: &'a mut [u8], } // FIXME: https://github.com/rust-lang/rust/issues/31580 // , . // // ( , ) fn _hack_project_ref<'a, T>(v: &'a T) -> <Ref_<T> as LifetimeToType<'a>>::Output { v } fn _hack_project_ref_mut<'a, T>(v: &'a mut T) -> <RefMut_<T> as LifetimeToType<'a>>::Output { v } fn _hack_project_my_type<'a>(v: MyType<'a>) -> <MyType_ as LifetimeToType<'a>>::Output { v } // ( ) impl<'x, T> RefIterator for Iter<'x, T> { type TypeCtor = Ref_<T>; fn next<'a>(&'a mut self) -> Option<<Self::TypeCtor as LifetimeToType<'a>>::Output> where Self::TypeCtor: LifetimeToType<'a> { if self.slice.is_empty() { None } else { let (l, r) = self.slice.split_at(1); self.slice = r; Some(_hack_project_ref(&l[0])) } } } impl<'x, T> RefIterator for IterMut<'x, T> { type TypeCtor = RefMut_<T>; fn next<'a>(&'a mut self) -> Option<<Self::TypeCtor as LifetimeToType<'a>>::Output> where Self::TypeCtor: LifetimeToType<'a> { if self.slice.is_empty() { None } else { let (l, r) = mem::replace(&mut self.slice, &mut []).split_at_mut(1); self.slice = r; Some(_hack_project_ref_mut(&mut l[0])) } } } impl<'x> RefIterator for MyIter<'x> { type TypeCtor = MyType_; fn next<'a>(&'a mut self) -> Option<<Self::TypeCtor as LifetimeToType<'a>>::Output> where Self::TypeCtor: LifetimeToType<'a> { if self.slice.is_empty() { None } else { let split = cmp::min(self.slice.len(), 5); let (l, r) = mem::replace(&mut self.slice, &mut []).split_at_mut(split); self.slice = r; let my_type = MyType { slice: l, index: split / 2 }; Some(_hack_project_my_type(my_type)) } } } // ! fn main() { let mut data: [u8; 12] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; { let mut iter = Iter { slice: &data }; while let Some(v) = iter.next() { println!("{:?}", v); } } { let mut iter = IterMut { slice: &mut data }; while let Some(v) = iter.next() { println!("{:?}", v); } } { let mut iter = MyIter { slice: &mut data }; while let Some(v) = iter.next() { println!("{:?} {}", v.slice, v.index); } } }
use std::rc::Rc; use std::sync::Arc; use std::ops::Deref; // T -> Output trait RcLike<T> { type Output; fn new(data: T) -> Self::Output; } // struct Rc_; struct Arc_; impl<T> RcLike<T> for Rc_ { type Output = Rc<T>; fn new(data: T) -> Self::Output { Rc::new(data) } } impl<T> RcLike<T> for Arc_ { type Output = Arc<T>; fn new(data: T) -> Self::Output { Arc::new(data) } } struct Node<Ref, T> // `where` ( - ) where Ref: RcLike<Node<Ref, T>>, { elem: T, // : Option<Rc<Node<Rc_, T>> next: Option<<Ref as RcLike<Node<Ref, T>>>::Output> } struct List<Ref, T> where Ref: RcLike<Node<Ref, T>>, { head: Option<<Ref as RcLike<Node<Ref, T>>>::Output> } impl<Ref, T, RefNode> List<Ref, T> where Ref: RcLike<Node<Ref, T>, Output=RefNode>, RefNode: Deref<Target=Node<Ref, T>>, RefNode: Clone, { fn new() -> Self { List { head: None } } fn push(&self, elem: T) -> Self { List { head: Some(Ref::new(Node { elem: elem, next: self.head.clone(), })) } } fn tail(&self) -> Self { List { head: self.head.as_ref().and_then(|head| head.next.clone()) } } } fn main() { // ( , ) let list: List<Rc_, u32> = List::new().push(0).push(1).push(2).tail(); println!("{}", list.head.unwrap().elem); // 1 let list: List<Arc_, u32> = List::new().push(10).push(11).push(12).tail(); println!("{}", list.head.unwrap().elem); // 11 }
// , // "" // . , // , . // ( Vec, ). // // " ", // . // , , // ( ?). // , , // , . // . // (let idx = arr.validate(idx)). // // - // , , // ( moving values in/out try!). // , // , , , . // // API ( , Vec -- `push` `pop`. // . // // , , // , // // gereeter // BTreeMap. ST Monad Haskell . // // , // &[T] &mut [T]. fn main() { use indexing::indices; let arr1: &[u32] = &[1, 2, 3, 4, 5]; let arr2: &[u32] = &[10, 20, 30]; // ( , ) indices(arr1, |arr1, it1| { indices(arr2, move |arr2, it2| { for (i, j) in it1.zip(it2) { println!("{} {}", arr1.get(i), arr2.get(j)); // // println!("{} ", arr2.get(i)); // println!("{} ", arr1.get(j)); } }); }); // , let _a = indices(arr1, |arr, mut it| { let a = it.next().unwrap(); let b = it.next_back().unwrap(); println!("{} {}", arr.get(a), arr.get(b)); // a // , }); // , let (x, y) = indices(arr1, |arr, mut it| { let a = it.next().unwrap(); let b = it.next_back().unwrap(); (arr.get(a), arr.get(b)) }); println!("{} {}", x, y); // : !? // (: ) } mod indexing { use std::marker::PhantomData; use std::ops::Deref; use std::iter::DoubleEndedIterator; // Cell<T> T; Cell<&'id _> `id` . // , // 'id "" . type Id<'id> = PhantomData<::std::cell::Cell<&'id mut ()>>; pub struct Indexer<'id, Array> { _id: Id<'id>, arr: Array, } pub struct Indices<'id> { _id: Id<'id>, min: usize, max: usize, } #[derive(Copy, Clone)] pub struct Index<'id> { _id: Id<'id>, idx: usize, } impl<'id, 'a> Indexer<'id, &'a [u32]> { pub fn get(&self, idx: Index<'id>) -> &'a u32 { unsafe { self.arr.get_unchecked(idx.idx) } } } impl<'id> Iterator for Indices<'id> { type Item = Index<'id>; fn next(&mut self) -> Option<Self::Item> { if self.min != self.max { self.min += 1; Some(Index { _id: PhantomData, idx: self.min - 1 }) } else { None } } } impl<'id> DoubleEndedIterator for Indices<'id> { fn next_back(&mut self) -> Option<Self::Item> { if self.min != self.max { self.max -= 1; Some(Index { _id: PhantomData, idx: self.max }) } else { None } } } pub fn indices<Array, F, Out>(arr: Array, f: F) -> Out where F: for<'id> FnOnce(Indexer<'id, Array>, Indices<'id>) -> Out, Array: Deref<Target = [u32]>, { // . // (, // F). , `indices` // , . // // // , `'static`, , // *this*. . // , , // // , . // // , // , , . // , , // . let len = arr.len(); let indexer = Indexer { _id: PhantomData, arr: arr }; let indices = Indices { _id: PhantomData, min: 0, max: len }; f(indexer, indices) } }
Source: https://habr.com/ru/post/307616/
All Articles