this post was submitted on 18 Dec 2025
220 points (99.1% liked)

Programmer Humor

39504 readers
314 users here now

Post funny things about programming here! (Or just rant about your favourite programming language.)

Rules:

founded 6 years ago
MODERATORS
 
you are viewing a single comment's thread
view the rest of the comments
[–] TimeSquirrel@kbin.melroy.org 3 points 10 hours ago (6 children)

Is this just like the equivalent of a getter method in C++?

[–] brandon@piefed.social 1 points 10 hours ago* (last edited 10 hours ago) (4 children)

It's more like a method that can throw an exception. Rust doesn't really have exceptions, but if you have a Result or Option type you can Unwrap it to get just the T. But if there's no T to get (in the case of an Error type for Result for None for Option) the call panics.

[–] eldavi@lemmy.ml 1 points 9 hours ago (3 children)

so you have to wrap everything in a try/catch?

[–] balsoft@lemmy.ml 4 points 8 hours ago* (last edited 8 hours ago)

Rust does not have exceptions. You never have to try/catch. Functions usually encode the possible failures in their types, so you'd have something like this C++ snippet:

struct HttpError {
  std::string message;
  int responseCode;
}

struct FsError {
  std::string message;
}

typedef std::variant<HttpError, IoError> FileDownloadError;

std::variant<std::filesystem::path, FileDownloadError> downloadFile(std::string url) { /* ... */ }

And then the caller of downloadFile has to decide what to do if it returns an error:

auto res = std::visit(overloaded {
	[](FileDownloadError e) { /* ignore error, or handle it somehow, and return a new path */ },
	[](std::filesystem::path p) { return p; }
}, downloadFile(url));

/* res is guaranteed to be a valid std::filesystem::path, you don't have to care about errors from downloadFile anymore */

However, Rust makes this whole thing a lot easier, by providing syntax sugar, and there are helper libraries that reduce the boilerplate. You usually end up with something like

#[derive(Error, Debug)]
enum FileDownloadError {
  #[error("HTTP request failed")]
  HttpError(http::status::StatusCode),
  #[error("Filesystem error: {0}")
  FSError(#[from] std::io::Error),
}

fn download_file(String url) -> Result<Path, FileDownloadError> {/* ... */}

(notice the #[from], which forwards the error message etc from the std::io::Error type)

The Result type is kind of like a std::variant with two template arguments, and, mostly by convention, the first one denotes the successful execution, while the second one is the error type. Result has a bunch of methods defined on it that help you with error handling.

Consumer code is something like this:

let res : Path = download_file(url).unwrap_or_else(|e| {
  /* Ignore the error or handle it. You have to return a new path here */
});

/* res is guaranteed to be a valid Path, you don't have to care about errors from download_file anymore */

Or

let res : Path = download_file(url)?;

/* res is guaranteed to be a valid Path, you don't have to care about errors from download_file anymore */

Which will just forward the error to your caller (but your function has to return Result as well), or proceed with the execution if the function succeeded.

Finally, download_file(url).unwrap() is if you can neither ignore, nor handle, nor pass the error to the caller. It will abort if the function fails in any way, and there's no (practical) way to catch that abort.

load more comments (2 replies)
load more comments (2 replies)
load more comments (3 replies)