This commit is contained in:
AF 2023-07-31 22:13:13 +00:00
parent 28f28b8298
commit 3b5bbb50d5
8 changed files with 87 additions and 2 deletions

View File

@ -5,6 +5,9 @@ multilingual = false
src = "src"
title = "Exercises"
[rust]
edition = "2021"
[build]
build-dir = "book"
create-missing = false

View File

@ -7,3 +7,6 @@
- [test1.rs (refbind)](./exercises/refbind.md)
- [A/A1/A2](./exercises/multiple_blanket.md)
- [BoolStream](./exercises/bool_stream.md)
- [RcChars](./exercises/rcchars.md)
- [Chapter 2](./chapter_2.md)
- [AnyStr](./exercises/anystr.md)

1
src/chapter_2.md Normal file
View File

@ -0,0 +1 @@
# Chapter 2

3
src/exercises/anystr.md Normal file
View File

@ -0,0 +1,3 @@
Create something similar to [Python's `typing.AnyStr`].
[Python's `typing.AnyStr`]: https://docs.python.org/3/library/typing.html#typing.AnyStr

View File

@ -1,6 +1,29 @@
Make `test_covariance` compile by making `BoolStream<'a>` covariant `'a`. Restrictions:
- Can only change implementation details of `BoolStream` and its methods and add extra items outside of what's given, i.e. no signature/test change.
- Changed version must behave the same way.
Consider the following code:
```rust,compile_fail
pub struct BoolStream<'a>(
Box<dyn 'a + FnOnce() -> (bool, BoolStream<'a>)>,
);
impl<'a> BoolStream<'a> {
pub fn new(f: impl 'a + FnOnce() -> (bool, Self)) -> Self {
Self(Box::new(f))
}
pub fn next(self) -> (bool, Self) {
self.0()
}
}
fn test_covariance<'a: 'b, 'b>(e: BoolStream<'a>) -> BoolStream<'b> {
e
}
```
Why does it fail to compile?
```rust
pub struct BoolStream<'a>(
// change this

50
src/exercises/rcchars.md Normal file
View File

@ -0,0 +1,50 @@
[`Chars`] but keeping a strong reference ([`Rc`]) to the string.
[`Chars`]: https://doc.rust-lang.org/std/str/struct.Chars.html
[`Rc`]: https://doc.rust-lang.org/std/rc/struct.Rc.html
```rust
# mod rcchars {
# pub struct RcChars { _rc: std::rc::Rc<String>, chars: std::mem::MaybeUninit<std::str::Chars<'static>> }
# impl Iterator for RcChars {
# type Item = char;
# fn next(&mut self) -> Option<Self::Item> { unsafe { self.chars.assume_init_mut() }.next() }
# }
# impl RcChars {
# pub fn from_rc(rc: std::rc::Rc<String>) -> Self {
# let mut new = Self { _rc: rc, chars: std::mem::MaybeUninit::uninit() };
# new.chars .write(unsafe { &*std::rc::Rc::as_ptr(&new._rc) }.chars());
# new
# }
# }
# impl From<std::rc::Rc<String>> for RcChars {
# fn from(value: std::rc::Rc<String>) -> Self { Self::from_rc(value) }
# }
# impl Drop for RcChars {
# fn drop(&mut self) { unsafe { self.chars.assume_init_drop() } }
# }
# }
# use std::rc::Rc;
# use rcchars::RcChars;
{
let rc = Rc::new("abc".to_string());
let rcc = RcChars::from(rc.clone());
drop(rc);
assert_eq!(rcc.collect::<Vec<_>>(), ['a', 'b', 'c']);
}
{
let rc = Rc::new("abc".to_string());
let rcc = RcChars::from(rc);
let rcc = Box::new(rcc);
assert_eq!(rcc.collect::<Vec<_>>(), ['a', 'b', 'c']);
}
```
## Solutions
- [Solution] used in rattlescript.
- [Same solution] but with some extra comments.
- [Another solution].
[Solution]: https://github.com/HavenSelph/rattlescript/blob/f8bafb8b063b9bf056efb1ea14188db0624d981c/src/interpreter/value.rs#L21-L50
[Same solution]: https://gist.github.com/timotheyca/7e46c9734653b2fcbe826ea4d13b9aa0
[Another solution]: https://gist.github.com/timotheyca/bc419e0997d6f7ea5722fd2823a78c62

View File

@ -7,7 +7,7 @@ fn refbind<T, F: Fn(&T) -> Option<&T>>(f: F, fa: Option<&T>) -> Option<&T> {
}
}
# }
# fn refbind<'a,'b,T:'a+?Sized>(f:impl'a+Fn(&'a T)->Option<&'b T>,fa:Option<&'a T>)->Option<&'b T>{fa.and_then(f)}
# fn refbind<'a,'b,T:'a+?Sized>(f:impl 'a+Fn(&'a T)->Option<&'b T>,fa:Option<&'a T>)->Option<&'b T>{fa.and_then(f)}
// don't change anything below

View File

@ -2,9 +2,11 @@
Random Rust exercises.
**Warning: this is a live-edited website, errors and accidental spoilers are to be expected.**
# Solutions
Currently solutions are only provided in a non-human-readable form in the page source.
Currently solutions are mostly provided in a non-human-readable form in the page source.
Those are mostly intended for testing that the exercise is even possible to solve.
```rust
# /*