Шефа от първото домашно се завърна (The Fizz Boss) и този път иска повече performance.
Какъв е тоя вектор? Много място заема в паметта, по-добре да е итератор. И как така ще клонираме низове, да не пишем руби, я връщайте някакви references!
Не можем винаги да връщаме references, защото искаме да връщаме и числа, конвертирани към низове, а има доста такива... Няма къде да ги държим. Но може да използваме std::borrow::Cow, за да държим reference когато можем и own-ната стойност, когато не можем:
use std::borrow::Cow;
pub struct FizzBuzzer {
labels: [String; 3],
}
impl FizzBuzzer {
pub fn new(labels: [String; 3]) -> Self {
FizzBuzzer { labels }
}
/// Връщаме нова структура `FizzBuzzerIter`, която има връзка с оригиналния FizzBuzzer и
/// каквото още ѝ трябва, за да може да връща резултати.
pub fn iter(&self) -> FizzBuzzerIter {
todo!()
}
}
pub struct FizzBuzzerIter {
fizzbuzzer: &FizzBuzzer,
// каквито други полета ви трябват
}
Забележете, че FizzBuzzerIter има reference към някакъв FizzBuzzer. Ако се опитате да компилирате този код досега, ще получите грешка, защото не сме сложили lifetime анотации, които са нужни -- вие трябва да добавите каквито трябва. Свободни сте да добавите каквито други полета искате в тази структура също.
impl Iterator for FizzBuzzerIter {
type Item = Cow<str>;
/// Очакваме всяко извикване на тази функция да връща следващото естествено число, започващо от
/// 1:
///
/// - Ако числото се дели на 3, връщаме `Cow::Borrowed`, държащо reference към `labels[0]`
/// - Ако числото се дели на 5, връщаме `Cow::Borrowed`, държащо reference към `labels[1]`
/// - Ако числото се дели на 15, връщаме `Cow::Borrowed`, държащо reference към `labels[2]`
/// - Иначе, връщаме `Cow::Owned`, държащо числото, конвертирано до `String`
///
fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}
Ще трябва да прочетете документацията на std::borrow::Cow, за да разберете как се използва. По-досадното е, че ще трябва и да разберете какви lifetime анотации да сложите, за да може кода да се компилира.
Ето ви пълния тест, който ще използваме, за да оценим задачата: rust-homework/challenge_02/test_full.rs. Необичайно е да пуснем пълния тест, но в случая предизвикателството е да компилирате кода -- ако успеете да го компилирате с минаващ тест, ще си заслужите точките.
Съветваме ви да започнете от това да връщате String от итератора, за по-лесно -- test_basic би трябвало да минава с това даже, стига да закоментирате останалите. Така ще имплементирате итератора на сравнително спокойствие. После можете да смените type Item обратно на Cow и да видите как да преминете към него.
Compiling solution v0.1.0 (/tmp/d20201120-2816268-1xcqwfd/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.65s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-1bhclwx/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.74s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-1xmqkol/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.78s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-1y8amjr/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.68s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-3lgsno/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.71s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-16yalhp/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.66s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
/// Връщаме нова структура `FizzBuzzerIter`, която има връзка с оригиналния FizzBuzzer и
/// каквото още ѝ трябва, за да може да връща резултати.
pubfniter(&self)->FizzBuzzerIter{
FizzBuzzerIter{fizzbuzzer:self,num:1}
}
}
pubstructFizzBuzzerIter<'a>{
fizzbuzzer:&'aFizzBuzzer,
num:i32,
// каквито други полета ви трябват
}
impl<'a>IteratorforFizzBuzzerIter<'a>{
typeItem=Cow<'a,str>;
/// Очакваме всяко извикване на тази функция да връща следващото естествено число, започващо от
/// 1:
///
/// - Ако числото се дели на 3, връщаме `Cow::Borrowed`, държащо reference към `labels[0]`
/// - Ако числото се дели на 5, връщаме `Cow::Borrowed`, държащо reference към `labels[1]`
/// - Ако числото се дели на 15, връщаме `Cow::Borrowed`, държащо reference към `labels[2]`
/// - Иначе, връщаме `Cow::Owned`, държащо числото, конвертирано до `String`
///
fnnext(&mutself)->Option<Self::Item>{
letmutlabel="";
letmutnumber=String::from("");
ifself.num%15==0{
label=&self.fizzbuzzer.labels[2];
}
elseifself.num%3==0{
label=&self.fizzbuzzer.labels[0];
}
elseifself.num%5==0{
label=&self.fizzbuzzer.labels[1];
}
else{
number=self.num.to_string();
}
self.num+=1;
iflabel==""{
Some(Cow::Owned(number))
}
else{
Some(Cow::Borrowed(label))
}
}
}
Compiling solution v0.1.0 (/tmp/d20201120-2816268-90q8lm/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.69s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-m3e7l/solution)
Finished test [unoptimized + debuginfo] target(s) in 3.67s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-nr30kl/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.65s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
// apparently post-increment is too confusing for some people
// and we can't have nice things in order to protect Cletus from himself
Some(fizzbuzz(self.current_number-1))
}
}
Compiling solution v0.1.0 (/tmp/d20201120-2816268-15m8068/solution)
Finished test [unoptimized + debuginfo] target(s) in 2.00s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-1lbwk9q/solution)
Finished test [unoptimized + debuginfo] target(s) in 2.37s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 4 tests
test tests::it_works ... ok
test tests::test_basic ... ok
test tests::test_cow ... ok
test tests::test_labels ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-3f7t6p/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.67s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-1mggv58/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.69s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-19hskj9/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.75s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-9scfo6/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.73s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-1bee2ck/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.64s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-1uf85f5/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.68s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-tbxsmh/solution)
Finished test [unoptimized + debuginfo] target(s) in 3.71s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-kzs73n/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.71s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-w3jhnt/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.65s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-augn77/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.66s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-1k4vvod/solution)
Finished test [unoptimized + debuginfo] target(s) in 3.73s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20201120-2816268-lwp047/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.87s
Running target/debug/deps/solution-fd5ff8031b6e4b61
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-589a43f0f4b10ca3
running 3 tests
test solution_test::test_basic ... ok
test solution_test::test_cow ... ok
test solution_test::test_labels ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out