Optionals ve Nullable type arasındaki fark nedir


15

Swift var Optionals. C # Nullabletürleri vardır.

Her ikisinin de aynı amaca hizmet ettiğini söyleyebildiğim kadarıyla, bir tür değerin yanı sıra, değişkenin değeri olup olmadığını veya tanımlanmamış (başlatılmamış) bilgileri depolarlar.

Soru Optionalssadece Nullablefarklı isimlere sahip türler mi yoksa başka kavramsal farklılıklar var mı?

Başka bir deyişle, kavramın kendisi hakkında ya da olmayan diller bağlamında konuşmak Optionalsya da Nullablesterimin kullanılmasının önemi var mı?

Bu işlevselliği dilde uygularken, türü Optionals<T>veyaNullable<T>


Bir dil agnostik bakış açısından, özdeştirler. Bununla birlikte, bir dil kavramları farklılaştırabilir (örneğin, desen eşleşmesinin uygulanıp uygulanmadığı).
Thomas Eding

C # (bu sadece bir monadic desen var) çok Seçenek olabilir: github.com/louthy/language-ext
Den

2
Bir boş başvuru (veya işaretçi içeren dillerde NULL işaretçisi) kullanmak, bazı dillerin isteğe bağlı değerleri göstermek için kullandığı bir saldırıdır, yani bir değeri olan veya hiç değeri olmayan bir kap. Bu, yalnızca başvuruları (veya işaretçileri) temel alan bir tür isteğe bağlı olarak düşünebileceğiniz bir sınırlamaya sahiptir. Yani, örneğin, Java'da bir tamsayıyı bir nesneye sarmadan isteğe bağlı yapamazsınız (örn. Tamsayı). Diğer diller, belki Haskell'de, Scala'da Seçenek vb. Gibi başka herhangi bir türü saran genel tür olarak isteğe bağlı türler sağlar.
Giorgio

Yanıtlar:


5

Çok benzer şekilde çalışsalar bile farklı bir çağrışım vardır. Microsoft dışındaki herkes (buraya rulo ekleyin) kullanır nullve nullableyalnızca referans bağlamında kullanır . Optionsve Maybesgenel olarak hem referanslara hem de değerlere atıfta bulunulmaktadır, özellikle de referans şeffaflığının bir değer ile bir referans arasında çok fazla fark olmadığı anlamına gelen fonksiyonel programlama dillerinde.

Başka bir deyişle, kavramın kendisi hakkında ya da olmayan diller bağlamında konuşmak Optionalsya da Nullableshangi terimin kullanıldığı önemli midir?

Optionsgeniş bir kitle arasında en az karışıklığa neden olan terimdir. Sadece C # programcıları, Nullablebir değer türüne potansiyel olarak uygulanacağını düşünür ve bence bunların çoğu en azından bir şeyin ne olduğunun farkındadır Option.


Microsoft ve SQL tasarımcıları dışındaki herkes, demek istediğini düşünüyorum.
Jules

9

.NET'te iki tür kategori vardır: başvurular ve değerler (int, double, structs, enums vb.). Farklılıkları arasında bir referansın olabileceği gerçeği, nullbir değer olamaz. Bu nedenle, bir değer türünüz varsa ve "isteğe bağlı" veya "bilinmeyen" anlambilimi iletmek istiyorsanız, bunu süsleyebilirsiniz Nullable<>. Nullable<>Yalnızca değer türlerini kabul etmek için türe göre sınırlandırıldığını unutmayın (bir where T : structyan tümcesi vardır). Nullable<>ayrıca derleyiciden özel bir nulldeğere sahiptir, burada bir değer şunlardan korunur NullReferenceExceptions:

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

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

(Vb Scala, F #, Haskell, Swift gibi) fonksiyonel dillerde o yaygındır nulliçin mevcut değil . Çünkü tüm insanlar varlığını kötü bir fikirnull olarak görüyorlar ve dil tasarımcıları bu sorunu çözerek çözüme kavuşturmaya karar verdiler.

Bu, yine bu dillerde değeri olmayan bir değeri temsil etmenin bir yoluna ihtiyacımız olduğu anlamına gelir . OptionTürü girin (adlandırma değişir, MaybeHaskell'de denir ). Bu Nullable, değerin "Yok" veya "Bilinmeyen" vb. Olduğu durumu eklemek için bir tür sarmasıyla benzer bir iş yapar .

Gerçek fark, uyguladığınız diller tarafından size verilen ekstra fonksiyonlardadır Option. Örnek olarak, al Option.map(sözde kodda):

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

G gibi zincirleme fonksiyonları Option.map, C # 'da her yerde gördüğünüz tipik null kontrol kazan plakasından kaçınmanın güçlü bir yoludur:

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

C # içindeki Null olabilecek eşdeğeri şöyle olur:

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);
}

Ancak bu, yalnızca değer türleri için çalışacağı için C # 'da sınırlı bir yardımcı program içerir.

C # 'ın yeni sürümü , yalnızca yöntemler ve özellik erişimcileri için geçerli olması dışında ?., Option.mapişleve benzeyen "null çoğaltma" operatörünü ( ) sunar . Yukarıdaki örnek yeniden yazılır

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

C # saf olmayan işlevsel bir dildir (tıpkı F # gibi). Ayrıca F # 'da null değeri var.
Den

C # 6 null değer baskısına sahiptir, bu nedenle kodunuzun en azından bir kısmı güncel değildir: github.com/dotnet/roslyn/wiki/… roslyn.codeplex.com/discussions/540883
Den

Ayrıca seçenekleri uygulamak kolaydır: github.com/louthy/language-ext
Den

1
@Den: C # FP'ye doğru eğilirken F # FP'ye doğru eğilir. Varsayılan olarak körelme ve değiştirilebilirlik olmaması, C #'ın ciddi fonksiyonel programlama için uygun olmadığı anlamına gelir. Cevabın sonunda null yayılımından bahsettim. Seçenekler gerçekten C # 'da uygulanması kolaydır, ancak bu sorudan kaynaklanmaktadır.
AlexFoxGill

4
@ Bence yorumlarınızda bazı kötü kelimeler var. Saf olmayan fonksiyonel dil, yan etkilere izin veren fonksiyonel bir dildir. C # bazı işlevsel özelliklere sahip olabilir ve bunları büyük bir etki yaratmak için kullanabilirsiniz, ancak işlevsel bir dil değildir. Her iki dilin de% 100 işlevsel olmadığını kastediyorsunuz, ancak F # çoğu zaman işlevsel bir dil olan OCaml'e çok yakın. İşlevsel paradigmadan sapmaları ne olursa olsun, çoğunlukla yabancı .NET kodu ile birlikte çalışabilir. Vaka, nullF # türleri için geçerli bir değer değil.
Doval
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.