Result<TypeIfOk, TypeIfErr> -> if the function returns Ok, it will be of type Ok(value of TypeIfOk), if it returns Err it will be of type Err(value of TypeIfErr).
What .unwrap() does is:
If I get Ok, than get me the value of TypeIfOk(get me the value that Ok stores), so I don't have to match on it, or use some other mechanism to get the value that is stored in it.
If I get Err, I don't care, just crash the application(by crash I mean Rust's panic).
That's basically what the user says to the compiler when calling unwrap() on Result.
Since I've hard-coded Queen::new to always return Err(InvalidQueen),then my call to uwrap() should panic, right? But when I run that playground example, I don't get a panic. I get a failing test.
How I see it is that .unwrap() will panic, but at runtime, this is an error at compile-time. .unwrap() returns type T or panics. Because type T in this case is Queen, at compile time it fails because InvalidQueen is not the same type that unwrap() returns, which is Queen, and assert_eq expects to compare the same types.
Yes, Message::Quit or Message::Move { x: 1, y: 2 } are expressions of type Message; even though variants in enum declarations look like struct declarations, they don't create separate types. (There was a proposal that would change this, actually, not sure what happened to it...)
Yes, Quit is a variant. It's uppercase, but it's ultimately a value, not a type. Similarly, Write is also a value, though on its own Write isn't a complete value, it has a contained String value too. Both Quit and Write are variants, and cannot be used as types.
This is better, btw:
fn test_queen_with_invalid_position() {
let white_queen = Queen::new((-1,2));
assert!(white_queen.is_err())
}
Thanks for pointing out is_err. That has improved our tests. I'm also trying out an alternate API for creating Queen structs. I find this better, but am not sure about having to Unwrap every usage of can_attack.
I've heard the "don't use unwrap()" advice before. But I'm not sure how to follow it in this case. In the test suite for this exercise, I've ended up unwrapping the results of Queen::new because that seemed most expedient. I guess I could go the expect route and have some a custom panic message, but it didn't seem necessary considering the usage of this code.
Yes, I agree with jethrogb, in tests it is perfectly fine to unwrap().
In regular code, which can actually panic to the user, it should be avoided to do so.
Rustaceans seem to use the same conventions as "functional" languages like Haskell. In Haskell they would define "data Boolean = True | False" and then code could say, "let truth = False". In Rust they followed that practice. Likewise in both languages functions normally aren't capitalized. A few conventions aren't copied from Haskell so I won't press this point too far. I would say though, from an exercise I did with some colleagues to define some coding conventions we would follow, there are only a few interesting name patterns and there are far more sorts of things to name.
From those five (no one likes the first one, so it's really four), one must choose the convention for each of usually more than four kinds of naming opportunities:
functions, classes (c++ python et al) structs, enums, enum 'variants', global, local, and/or member variables, constants, macros, modules, files, executables, ...