のオプションの仕組みはなんですか?私はApressのエキスパートF#の本を読んでいます。おもちゃのF#ライブラリを構築する際に参考にしていますが、把握できなかった点が1つあります。これは「オプション」タイプです。F#
どのように動作し、実際の使用状況はどうですか?
のオプションの仕組みはなんですか?私はApressのエキスパートF#の本を読んでいます。おもちゃのF#ライブラリを構築する際に参考にしていますが、把握できなかった点が1つあります。これは「オプション」タイプです。F#
どのように動作し、実際の使用状況はどうですか?
オプションタイプは、C#で少なくともNullable<T>
に類似した参照タイプです。 Option<T>
の値は、カプセル化された値がないことを意味するNone
、またはT
の特定の値を持つSome
のいずれかです。及び方法は、C#でString
値がいずれか null参照である、又はは、文字列オブジェクトを参照 - これは単にC#でNullable<int>
がいずれかヌル値であり、又はが関連int
を有している方法のようです。
オプション値を使用する場合、あなたは一般的に二つの経路指定 - が関連する値、およびが存在しないものがある場合のための1つを。言い換えれば、このコード:私は一般的なアイデアがあなたは(まあ、ほとんど)「いいえ関連する値/オブジェクトを処理するためにを強制ことであると信じ
int StringLength(string str)
{
if (str != null)
{
return str.Length;
}
else
{
return -1;
}
}
:
let stringLength (str:Option<string>) =
match str with
| Some(v) -> v.Length
| None -> -1
はに似ています"大文字小文字は、コードをより堅牢にします
値がオプションの場合に使用します。 1つの用途は、一種の「ヌルリファレンス」を有することである。
val x : int option ref = None
その後、後でxを「Some v」に変更することができます。
match !x with (* dereference x *)
None -> (* No value, do something *)
| Some v -> (* Value v, do something else *)
関数またはメソッドが値を「多分」または「任意に」返す必要がある場合に使用されます。 C#ではおそらくnullを返すか、Null Objectを返すか、値の型にNullableを返す可能性があります。
戻り値の欠点(最も一般的なケース)は、型が安全でないということです。nullはすべての型のインスタンスなので、後ほどすべての種類の毛状ヌル参照状況になります。
オプションタイプは、2つのコンストラクタを持つ、いわゆる識別されたユニオンタイプです。いずれも値がないことを明示的に示していません。基本的には、それは一般化されたヌルオブジェクトパターンです。
実世界で最もよく使用される例の1つは、.NetのTryParseパターンの場合です。議論のため
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!181.entry
の前半を参照してください。
その他の回答に追加するには、Optionタイプは何も特別なものではありません。これは別の差別化されたユニオンです。あなたは1行でそれを自分で定義することができます。
type 'a Option = None | Some of 'a
ユーティリティ、他の人が指摘したように、そのパターンマッチングは、安全にこれを解体できるようになるされ、代わりにnullをチェックするかどうかを示すために、いくつかのハック-回避策を使用します値は実際に値ではありません。
オプションタイプ使用して、機能パターン:あなたは、このようなツリーやリストなどの再帰的なデータ構造の一部を変更する必要がある場合
は、 既存のデータ構造としての限りを再利用したいと思うでしょう可能。オプションタイプ はこれを手伝うことができます。 これらの2つの関数は、数字5のすべての出現を7,に置き換えますが、最初のものはツリー全体をコピーします。 2番目のものはありません。
type Tree = Leaf of int
| Node of Tree * Tree
let rec replace_no_sharing tree =
match tree with
| Leaf 5 -> Leaf 7
| Leaf x -> Leaf x
| Node (a, b) -> Node (replace_no_sharing a, replace_no_sharing b)
let replace_with_sharing tree =
let rec replace_option tree =
match tree with
| Leaf 5 -> Leaf 7 |> Some
| Leaf x -> None
| Node (a, b) -> match replace_option a, replace_option b with
| None, None -> None
| Some a, Some b -> Node (a, b) |> Some
| Some a, None -> Node (a, b) |> Some
| None, Some b -> Node (a, b) |> Some
match replace_option tree with
| None -> tree
| Some tree -> tree
すべてのケースで必ずしも必要なわけではありませんが、わかりやすいテクニックです。