This article needs additional citations for verification .(January 2021) |
In functional programming, a result type is a monadic type holding a returned value or an error code. They provide an elegant way of handling errors, without resorting to exception handling; when a function that may fail returns a result type, the programmer is forced to consider success or failure paths, before getting access to the expected result; this eliminates the possibility of an erroneous programmer assumption.
std::expected<T,E>. [1] typeResultev=Okv|Erre. [2] Either type is used for this purpose, which is defined by the standard library as dataEitherab=Lefta|Rightb, where a is the error type and b is the return type. [3] Result<R, E> similar to Rust Result<T, E>, and vavr includes an interface Either<L, R> similar to Haskell Either a b. Because Java and Kotlin are cross-compatible, Java can use the Result type from Kotlin.valueclassResult<outT>. [4] type('a,'b)result=Okof'a|Errorof'btype. [5] enumResult<T,E>{Ok(T),Err(E)}. [6] [7] Either type, [8] however Scala also has more conventional exception handling.@frozenenumResult<Success,Failure>whereFailure:Error. [9] !T as the return type of a function. For example fn my_function() !string { ... }. Error Handling in V.The expected<T, E> class uses std::unexpected() to return the type E, and can return T directly.
importstd;usingFileInputStream=std::ifstream;usingString=std::string;usingStringStream=std::stringstream;usingPath=std::filesystem::path;enumclassFileError{MissingFile,NoPermission,// more errors here};std::expected<String,FileError>loadConfig(constPath&p)noexcept{if(!std::filesystem::exists(p)){returnstd::unexpected(FileError::MissingFile);}FileInputStreamconfig{p};StringStreambuffer;if(!config.is_open()){returnstd::unexpected(FileError::NoPermission);}buffer<<config.rdbuf();config.close();returnbuffer.str();}intmain(intargc,char*argv[]){Pathp{/* some path here */};if(conststd::expected<String,FileError>s=loadConfig(p);s.has_value()){std::println("Config contents: {}",s.value());}elseif(s.error()==FileError::MissingFile){std::println("Error: path {} not valid or missing!",p);}elseif(s.error()==FileError::NoPermission){std::println("Error: no permission to read file at path {}!",p);}else{std::unreachable();}}The result object has the methods is_ok() and is_err().
constCAT_FOUND:bool=true;fnmain(){letresult:Result<(),String>=pet_cat();ifresult.is_ok(){println!("Great, we could pet the cat!");}else{leterror:String=result.unwrap_err();println!("Oh no, we couldn't pet the cat: {}",error);}}fnpet_cat()->Result<(),String>{ifCAT_FOUND{Ok(())}else{Err(String::from("The cat is nowhere to be found!"))}}The Error type is an interface for iError.
constcat_found=truefnmain(){cat_name:=get_pet_cat_name()or{println("Oh no, we couldn't pet the cat!")exit(1)}println('Great,wecouldpetthecat'+cat_name)}fnget_pet_cat_name()!string{ifcat_found{return'Max'}else{returnerror('thecatisnowheretobefound')}}