SwiftにはOptionals
があります。 C#にはNullable
タイプがあります。
両方が同じ目的を果たしていると私が知る限り、変数には値があるかどうか、または未定義(初期化されていない)かどうかの情報がいくつかの型の値に保存されます。
問題は、名前が異なるOptionals
型Nullable
型だけですか、それとも他の概念的な違いがありますか?
言い換えれば、コンセプト自体について、またはOptionals
やNullables
を持たない言語のコンテキストで話す場合、どの用語が使用されるかは重要ですか?
言語でその機能を実装するとき、type Optionals<T>
またはNullable<T>
動作は非常に似ていますが、異なる意味合いがあります。 Microsoft以外の全員(ここにアイロールを挿入)は、参照のコンテキストでのみnull
およびnullable
を使用します。 Options
とMaybes
は、参照と値の両方を指すと一般に理解されています。特に、関数型プログラミング言語では、参照の透過性により値と参照の間に大きな違いはありません。
言い換えると、コンセプト自体について、または
Optionals
やNullables
を持たない言語のコンテキストについて話す場合、どの用語が使用されているかは重要ですか?
Options
は、幅広いオーディエンス間の混乱を最小限に抑えるための用語です。 C#プログラマーだけがNullable
を値の型に適用する可能性があると考えますが、それらのほとんどは少なくともOption
が何であるかを認識していると思います。
.NETには、referencesとvaluesの2つのタイプのカテゴリがあります。 (int、double、struct、enumなど)。それらの違いの中には、参照が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
タイプを入力します(命名法は異なり、HaskellではMaybe
と呼ばれます)。これは、値が「なし」または「不明」などのケースを追加するために型をラップするという点で、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#の新しいバージョンでは、「null伝播」演算子(?.
)が提供されています。これは、メソッドとプロパティアクセサーにのみ適用できることを除いて、Option.map
関数と似ています。上記のサンプルは書き換えられます
return service?.GetValue()?.Property?.Value;