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" src = "src"
title = "Exercises" title = "Exercises"
[rust]
edition = "2021"
[build] [build]
build-dir = "book" build-dir = "book"
create-missing = false create-missing = false

View File

@ -7,3 +7,6 @@
- [test1.rs (refbind)](./exercises/refbind.md) - [test1.rs (refbind)](./exercises/refbind.md)
- [A/A1/A2](./exercises/multiple_blanket.md) - [A/A1/A2](./exercises/multiple_blanket.md)
- [BoolStream](./exercises/bool_stream.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: 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. - 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. - 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 ```rust
pub struct BoolStream<'a>( pub struct BoolStream<'a>(
// change this // 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

@ -2,9 +2,11 @@
Random Rust exercises. Random Rust exercises.
**Warning: this is a live-edited website, errors and accidental spoilers are to be expected.**
# Solutions # 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. Those are mostly intended for testing that the exercise is even possible to solve.
```rust ```rust
# /* # /*