Loading article…
関数型プログラミングにおいて、結果型とは、戻り値またはエラーコードを保持するモナド型のことです。結果型は、例外処理に頼ることなく、エラーを処理する洗練された方法を提供します。失敗する可能性のある関数が結果型を返す場合、プログラマーは期待される結果にアクセスする前に、成功または失敗の経路を考慮することを余儀なくされます。これにより、プログラマーの誤った想定の可能性が排除されます。
std::expected<T,E>typeResultev=Okv|ErreEitherこの目的のために型が使用され、これは標準ライブラリで次のように定義されています。ここで、はエラー型、は戻り値の型です。[ 3 ]dataEitherab=Lefta|RightbabResult<R, E>はRustに似たインターフェースをResult<T, E>、vavrはEither<L, R>Haskellに似たインターフェースを提供していますEither a b。JavaとKotlinは相互互換性があるため、JavaはResultKotlinの型を使用できます。valueclassResult<outT>type('a,'b)result=Okof'a|Errorof'btypeenumResult<T,E>{Ok(T),Err(E)}Either型を定義していますが[ 8 ]、Scalaにはより従来型の例外処理もあります。@frozenenumResult<Success,Failure>whereFailure:Error!T関数の戻り値の型としてネイティブに実装されます。例fn my_function() !string { ... }: 。V でのエラー処理。クラスは型を返すためにをexpected<T, E>使用し、直接返すことができます。std::unexpected()ET
import std ;using std :: expected ; using std :: ifstream ; using std :: string ; using std :: stringstream ; using std :: unexpected ; using std :: filesystem :: path ;enum class FileError { MISSING_FILE , NO_PERMISSION , // その他のエラー};expected < string , FileError > loadConfig ( const path & p ) noexcept { if ( ! std :: filesystem :: exists ( p )) { return unexpected ( FileError :: MISSING_FILE ); } ifstream config { p }; stringstream buffer ; if ( ! config . is_open ()) { return unexpected ( FileError :: NO_PERMISSION ); } buffer << config . rdbuf (); config . close (); return buffer . str (); }int main ( int argc , char * argv []) { path p { "configs/my_config.txt" }; if ( const expected < String , FileError > s = loadConfig ( p ); s . has_value ()) { std :: println ( "Config contents: {}" , s . value ()); } else { switch ( s . error ) { case FileError :: MISSING_FILE : std :: println ( "Error: path {} not valid or missing!" , p ); break ; case FileError :: NO_PERMISSION : std :: println ( "Error: no permission to read file at path {}!" , p ); break ; // additional cases... default : std :: unreachable (); } } }Rustにおける列挙型はタグ付き共用体であり、パターンマッチングによる厳密な型チェックによって展開することができます。
const CAT_FOUND : bool = true ;fn main () { let result : Result < (), String > = pet_cat (); match result { Ok ( _ ) => println! ( "素晴らしい、猫を撫でることができました!" ), Err ( error ) => println! ( "ああ、猫を撫でることができませんでした: {error}" ) } }fn pet_cat () -> Result < (), String > { if CAT_FOUND { Ok (()) } else { Err ( String :: from ( "猫はどこにも見つかりません!" )) } }このError型は のインターフェースですiError。
const cat_found = truefn main () { cat_name : = get_pet_cat_name () or { println ( "ああ、猫を撫でることができませんでした!" ) exit ( 1 ) }println ( '素晴らしい、猫を撫でることができるよ' + cat_name ) }fn get_pet_cat_name () ! string { if cat_found { return ' Max ' } else { return error ( '猫は見つかりませんでした' ) } }