IMO, sort of!
All abstraction requires you to understand it at some level before you can quickly reason about it in code. But once you do, it allows you to reason about things at a higher level, rather than at a level where you have to focus on each detail individually. This is a net win for good abstractions that are (generally) simple and minimally leaky, but it can be a net loss for abstractions that are complicated.
You see this same conversation play out with functional looping constructs vs. imperative ones. Which is more readable?
for (int i = 0; i < a.len(); i++) {
a[i] = 0;
}
// vs.
a.map! { 0 }
If you don't know what `map!` does, the former. And many people argue for this for the sake of "simplicity".But when you understand functional iteration—which is generally a simple, non-leaky abstraction—the latter wins by a mile. And while you might look at this example and think "you're just saving a few lines of code", the latter not only completely eliminates entire classes of problems (off-by-one errors, slow calculation of `len()` for e.g., NUL-terminated strings, etc.) but knowing it also unlocks a bunch of additional useful tools like `reduce`, `filter`, and friends that reduce reams of boilerplate throughout your code while dramatically improving comprehensibility.
The same is true of `Option<T>` and `Result<T>`. They're wildly powerful and allow for rapid understanding of code without having to read and parse if-else branching to confirm that the logic is performing null checking or error handling (and more importantly, doing it correctly).
So you're not crazy for thinking the first example is the most readable of the three given your current knowledge. But you are crazy if you think the first example is preferable to learning the relatively simple abstractions of Option<T> and Result<T> which allow reasoning about things at a higher level and unlock extremely powerful tools in doing so.