rust-for-dotnet-devs icon indicating copy to clipboard operation
rust-for-dotnet-devs copied to clipboard

Some comments on the book

Open ChayimFriedman2 opened this issue 1 year ago • 3 comments

  • [ ] 1. In chapter 2.2, you give let s = &mut String::from("hello"); as an example of mutable string while let mut s = String::from("hello"); is more common and idiomatic.
  • [ ] 2. In the same chapter, you say let str = Box::new("Hello World!"); is equivalent to String in C# and has the type Box<str>, but actually it has the type Box<&str>. let str: Box<str> = Box::from("Hello World!"); is the way to go.
  • [ ] 3. In the same chapter, it is worth noting that format!() does not allow you to embed complex expressions in the literal (other than bare variable names), and requires you to pass them after (format!("{}", expr)).
  • [ ] 4. In the same chapter, it will be good to also mention the :#? specifier for pretty-printing debug format.
  • [ ] 5. In the same chapter, you can mention that Rust also has to_string(), and it is given for you for free whenever you implement Display.
  • [ ] 6. In chapter 2.4.6, you say "The self parameter has no type annotation since it's always the type to which the method belongs.". There are exceptions to this rule, thought (think self: Box<Self> etc.), however I don't know if they should be noted as they're pretty rare and advanced use case.
  • [ ] 7. In the same chapter, it probably should be noted that while properties are idiomatic in C#, in Rust we prefer exposing the fields directly when possible.
  • [ ] 8. In the same chapter, you say that there is no equivalent to with in Rust. This is not correct, because we have the struct update syntax (Struct { field1: value, field2: value, ..existing_instance }).
  • [ ] 9. In chapter 2.9, you may mention that std::ptr::eq() is somewhat like reference equality.
  • [ ] 10. In chapter 2.10, you may mention that there is a common shortcut to where in Rust: impl<T: Trait>.
  • [ ] 11. In chapter 2.13, it is probably good to mention that unlike in C#, a type isn't required to implement Error to be used in Result (althought it is strongly encouraged, at least for public types).
  • [ ] 12. In chapter 2.14, you may mention that the ? operator (already mentioned in the previous chapter) can also propagate an Option, and maybe also describe the trick of using an immediately invoked closure for an option block (until try blocks are stabilized).
  • [ ] 13. In the same chapter, you say the ! operator has no correspondence in Rust. This is mostly true, but unwrap() behaves similarly (ignore the Option/Result and cause a panic when missing). I know ! doesn't throw an exception directly in case of null, but using it incorrectly will often lead to a NullReferenceException.
  • [ ] 14. In chapter 2.16, you give subtyping as an example of coercion. This is not exactly true; subtyping is not a kind of coercion, and the proof is that you can use it even with nested types, where you cannot use coercions (&'static &'static str converts to &'a &'a str). An example of coercion is pointer unsizing (array reference to slice reference, or concrete reference to trait object reference).
  • [ ] 15. In chapter 3, you say the equivalent of static in C# is a read-only static. I don't understand why it has to be read only; Rust has mutable statics too (via interior mutability such as Mutex or the unsafe static mut).
  • [ ] 16. In chapter 5, it may be good to mention scoped threads for sharing data without 'static lifetime.

Stopped reading here (need to go), hope to continue read in the future... A good book 😃

ChayimFriedman2 avatar Apr 13 '23 17:04 ChayimFriedman2