OptionalsとNullableタイプの違いは何ですか


13

スイフトが持っていOptionalsます。C#にはNullable型があります。

両方が同じ目的を果たすことを伝えることができる限り、あるタイプの値に加えて、変数が値を持っているか未定義(初期化されていない)かを情報を保存します。

質問は、名前が異なるOptionalsだけのNullableタイプですか、または他の概念的な違いがありますか?

別の言い方をすると、概念自体について、または持っていない、Optionalsまたは持っていない言語の文脈で話すことはNullables、用語が使われていることを意味しますか?

言語でその機能を実装するとき、タイプに名前を付けるOptionals<T>か、Nullable<T>


言語にとらわれない観​​点から、それらは同一です。ただし、言語によって概念が区別される場合があります(たとえば、パターンマッチングが実施されるかどうか)。
トーマスエディング

C#もオプションを持つことができます(これは単なるモナドパターンです):github.com/louthy/language-ext
Den

2
NULL参照(またはポインターを使用する言語ではNULLポインター)を使用することは、一部の言語がオプションの値、つまり1つの値を持つか、まったく値を持たないコンテナーを表すために使用するハックです。これには、参照(またはポインター)に基づくタイプのみをオプションと見なすことができるという制限があります。そのため、たとえば、Javaでは、整数(整数など)をオブジェクトにラップしない限り、整数をオプションにすることはできません。他の言語は、HaskellのMaybe、ScalaのOptionなど、他の型をラップできる汎用型としてオプションの型を提供します。
ジョルジオ

回答:


5

動作は非常に似ていますが、異なる意味合いがあります。 マイクロソフト以外の全員(ここにアイロールを挿入)はnullnullable参照のコンテキストでのみ使用します。 OptionsそしてMaybes、一般的に、特に、参照透明性値と基準との間の大きな違いがないことを意味する関数型プログラミング言語で、参照と値の両方を指すと理解されます。

別の言い方をすると、概念自体について話すOptionalsNullables、持っていない言語の文脈で、どの用語が使用されているかは重要ですか?

Options幅広い聴衆の間で最も混乱を引き起こさない用語です。C#プログラマーのみNullableが値型に適用される可能性があると考えますが、ほとんどの人は少なくともaが何であるかを認識していると思いますOption


マイクロソフトとSQLのデザイナー以外の皆さん、私はあなたが意味すると思います。
ジュール

9

.NETには、参照(int、double、struct、enumなど)の2つのタイプのカテゴリがあります。それらの違いの中には、参照が可能になるのnullに対し、値は不可能であるという事実があります。したがって、値の型があり、「オプション」または「不明」のセマンティクスを伝えたい場合は、で装飾できますNullable<>Nullable<>は型によって制約され、値型のみを受け入れることに注意してください(where T : struct句があります)。Nullable<>コンパイラからの特別なアフォーダンスもあり、それによりnull値が以下から保護されNullReferenceExceptionsます。

string x = null;
x.ToString(); // throws a NullReferenceException

int? y = null;
y.ToString(); // returns ""

関数型言語(Scala、F#、Haskell、Swiftなど)では、存在nullないことが一般的です。これは、人々の存在を全体nullとして悪い考えだと考えており、言語設計者はそれを拒否することでこの問題に取り組むことを決めたからです。

これは、これらの言語で非価値を表す何らかの方法が再び必要であることを意味します。Optionタイプを入力します(命名法は異なり、MaybeHaskellで呼び出されます)。これはNullable、値が「なし」または「不明」などのケースを追加するために型をラップするという点で、同様のジョブを実行します。

本当の違いは、実装する言語によって提供される追加機能にありますOption。例として、Option.map(擬似コードで)以下を取ります:

function Option<T2> Option.map(opt: Option<T1>, mapFunc: T1 -> T2) {
    if (opt is None) return None
    else return Option<T2>(mapFunc(opt.Value))
}

次のような関数の連鎖Option.mapは、C#の至る所に見られる典型的なnullチェックボイラープレートを回避する強力な方法です。

if (service == null)
    return null;
var x = service.GetValue();
if (x == null || x.Property == null)
    return null;
return x.Property.Value;

C#でNullableに相当するものは次のとおりです。

public static Nullable<T2> Map<T1, T2>(this Nullable<T1> nullable, Func<T1, T2> f)
    where T1 : struct
    where T2 : struct
{
    if (!nullable.HasValue) return (T2?)null;
    else return (T2?) f(nullable.Value);
}

ただし、これは値型に対してのみ機能するため、C#のユーティリティは限られています。

C#の新しいバージョンは、メソッドとプロパティアクセサーのみに適用されることを除いて?.Option.map関数に似ている「null伝播」演算子()を提供します。上記のサンプルは書き換えられます

return service?.GetValue()?.Property?.Value;

C#は不純な関数型言語です(F#と同様)。また、F#にはnullがあります。
デン

C#6は、ので、あなたのコードの少なくとも一部が最新でない場合、NULL値の強制を持っていますgithub.com/dotnet/roslyn/wiki/... roslyn.codeplex.com/discussions/540883
デン

また、オプションの実装も簡単です:github.com/louthy/language-ext
Den

1
@Den:C#はOOPに傾いており、F#はFPに傾いています。デフォルトではカリー化と可変性がないため、C#は本格的な関数型プログラミングには適していません。答えの最後にヌル伝播について言及しました。オプションは確かにC#で実装するのは簡単ですが、それは質問から外れています。
AlexFoxGill

4
@Denコメントの中には、言葉の選択が不十分だと思います。不純な関数型言語は、副作用を許容する関数型言語です。C#には機能的な機能がいくつかあり、それらを使用して大きな効果を得ることができますが、機能的な言語ではありません。どちらの言語も100%機能しているわけではありませんが、F#はOCamlに非常に近く、ほとんどのアカウントで機能言語です。機能的パラダイムから逸脱するものはほとんど存在するため、外部の.NETコードと相互運用できます。null適切なケースは、F#タイプの有効な値ではありません。
ドーバル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.