Seçenek / Belki neden iyi bir fikir olarak kabul edilir ve kontrol edilen istisnalar değildir?


23

Örneğin, Scala gibi bazı programlama dilleri , ya bir değer içerebilen ya da içermeyen Optiontip kavramına (ayrıca adlandırılır Maybe) sahiptir.

Onlar hakkında okuduklarımdan, bu meseleyle baş etmekten daha üstün bir yol olarak kabul edilirler null, çünkü programcıyı açıkça çalışma zamanı sırasında havaya uçurmak yerine bir değerin bulunmadığı durumları göz önünde bulundurmaya zorlarlar.

Diğer yandan Java’daki Denetlenen İstisnalar, kötü bir fikir olarak görülüyor ve Java, bunları uygulayan tek yaygın kullanılan dil gibi görünüyor. Ancak, onların arkasındaki fikir Option, programcıyı bir istisna ortaya çıkabileceği gerçeğiyle başa çıkmak için açıkça zorlamak için tipe biraz benziyor .

OptionTürlerin sahip olmadığı işaretli İstisnalar ile ilgili ek sorunlar var mı? Ya da bu fikirler düşündüğüm kadar benzemiyor mu, ve İstisnalar için değil Seçenekler için açık işlem yapmaya zorlamak için iyi nedenler var mı?


Ayrıca Either e averi tipine bakınız .

4
Denetlenen istisnalar hakkında: gelişen kod temeli ve eksik / modası geçmiş belgeler içeren çok sayıda açık kaynaklı ve dahili Java kütüphanesi kullanıcısı olarak, Java’nın belirli istisnaları açıkça ilan edilmesini zorlamayacağı düşüncesindeyim. Beklenmedik bir şekilde, kötü yerlerde ortaya çıkan işlenmemiş çalışma zamanı hatalarının kabusu olur. Ve Java7 nihayet eski denemeler karmakarışıklığının çoğundan kurtularak neredeyse akıllıca davranıyor.
hyde

Yanıtlar:


24

Çünkü Options beste edilebilir. Hakkında yararlı yöntemlerden bir yeri vardır Optionhala akışına hassas kontrol izin verirken sen özlü kod yazmak için izin,: map, flatMap, toList, flattenve daha fazlası. Bunun nedeni, Optionbelli bir tür monad olması, nasıl besleneceğini çok iyi bildiğimiz bazı nesneler. Bu yöntemlere sahip değilseniz ve her zaman açık Optionolan bir eşleme deseni yapmak zorundaysanız ya da isDefinedsık sık aradıysanız, neredeyse kadar kullanışlı olmazlardı.

Bunun yerine, kontrol edilen istisnalar bir miktar güvenlik sağlarken, onları yakalamak veya yığınını kabarmalarına izin vermekten başka bir şey yapamazsınız (tip beyanında eklenen boyler ile).


1
İşaretli istisnalar ... daha fazla veya daha az aynı şekilde arasındaki farkı oluşturur try {/* bunch of complex code involving calls to 50 different methods that may throw SomeCheckedException */} catch(SomeCheckedException e) {/* operation failed, do something */}ve fromMaybe someDefaultValue (something >>= otherThing >>= ...50 other functions that may return Nothing...)tam olarak ne? Eski olanın size neyin yanlış gittiğiyle ilgili daha fazla ayrıntı vermesi dışında.
kullanıcı253751

14

Bununla birlikte, istisnalar ve Belki nesneleri aynı tip problemlerle ilgilenmez.

İstisnalar

İstisnai durumlar, yerel olmayan istisnai bir durumla (bazı durumlarda hata olur) başa çıkmanız gerektiğinde parlar. Örneğin, bir csv'yi ayrıştırıyorsunuz ve kendinizi yanlış biçimlendirme ile satırlara karşı korumak istiyorsunuz. Bir şeyin yanlış olduğunu bulduğunuz yer, bazı işlevler satır yinelemesinden uzaklaşıyor olabilir. En üst düzeyde bir istisna atarsanız (biçimlendirme sorununu öğrendiğiniz yerde), onu döngüde yakalayabilir, hatayı günlüğe kaydedebilir ve bir sonraki satıra geçebilirsiniz. Kodun geri kalanındaki hiçbir şeyi değiştirmeniz gerekmez.

Kontrol edilen istisna çok fazla acı ekler çünkü tüm ara işlevler atılabilir türü bildirmek zorundadır. Bu özellik orijinal amacı yitirir, bu yüzden bugünlerde popüler değillerdir.

Belki nesneler

Belki yerel olarak bir "başarısızlık" ile başa çıkarken nesneler seçilmelidir. Bu anlamda, bunlar bir başvuru kodu + pass'ın referans apı ya da null türüne göre değiştirilmeleridir.

Belki nesnesinin avantajı, açıkça bir şeyin yanlış olabileceğini beyan etmenizdir. Haskell'de, belki olmayan bir nesnenin değeri olmalı, yoksa program derlenmeyecek.

NULL olabilecek tiplerle ilgili sorun, tamamen güvenli olması için null değerini kontrol etmeniz gerektiğidir. "Bir şeyler yanlış olabilir" durumu varsayılandır.

Dönüş kodları + ref apis tarafından verilen sorun, çoğu insan için daha az okunabilir olmalarıdır.


1
@MattFenwick Geri bildiriminiz için teşekkür ederiz. Neden csv örneğinin bir anlam ifade etmediğini düşünüyorsunuz? OP, kazandan kaçınma teknikleri için gerçekten bir soru sormuyor ve uygulamalı fonktör ve monadlar gibi kelimelerin bu soru için fazla teknik olabileceği fikrine sahibim.
Simon Bergot

1
Java ile (işaretli istisnalar dışında diğer dillerden emin değiliz) IDE'lerin javadoc yorumların bir parçası olarak atma ve budama atma ve güncelleme işlemlerine özen gösterdiğini belirtmek isterim. Yani en azından bu kısım rahatsız edici ve kesinlikle acı verici değil. API tasarımı yaparken aralarında bir acı ya da nimet ya da bir şey olsun, bu başka bir mesele ...
hyde

5
@hyde: Sadece bir IDE'nin anlamsız kazan plakası üretimini otomatikleştirebilmesi, anlamsız kazan plakasının bir acı olmadığı anlamına gelmez.
Michael Shaw

2
@hyde: Fakat ağrı yok edilmedi. Anlamsız kazan hala orada, kodu sebepsiz yere karıştırıyor. Kazan için bir sebep varsa, nedir?
Michael Shaw

2
@MichaelShaw İstisna anlamsızsa, kaldırın: durumu yoksayın veya hata değerini döndürün. Bu bir hata veya onarılamaz durum ise: işaretlenmemiş istisna kullanın. Kalan nokta, anlamsız bir kazan plakası değil, örneğin parametre tipleri kadar önemlidir. Mevcut kitaplıkta kötü API ise, sarmalayıcı yöntemini / sınıfını, başka bir kitaplığı kullanarak ya da sadece kötü API'ye maruz kalmayı düşünün.
hyde

1

çünkü Maybedeğere gerçekten ihtiyacınız olana kadar hatayı işlemeyi erteleyebilirsiniz (bu, birkaç yöntem çağırılabilir)

kontrol istisna oysa ihtiyacı çağrı yerde ele alınması

istisnaların tek sebebi, neden başarısız olduğu hakkında daha fazla bilginin aktarılmasıdır (eğer MaybeErrorbir hata olduğunda bir atılabilir alan bulunan bir kimse yoksa )


2
Ancak, yöntemin bu istisnayı attığını ilan ederek kontrol edilen istisnaların ele alınmasını erteleyebilirim.
Mad Scientist

1
Belki de her yöne gidebilirken @ çağrı yığını kadar gider @MadScientist
cırcır ucube

5
Bence Maybetürleri hatalarla karıştırmamalısınız . Bir hatayı bildirmek için bir istisna, kısmi bir işlevin sonucunu temsil etmek için bir seçenek türü kullanılır. Bir kısmi işlev döndürme Nothingbir hata değildir.
Giorgio

@MadScientist: Bir yöntem çağrısı bir "Geçersiz değer" uyarısı verirse, çalıştırdıktan hemen sonra ifade. Buna karşılık, bir yöntem hemen yakalanmayan bir istisna atarsa, çağrıyı takip eden ifade atlanır. Kontrollü istisnaların çağrı yığınını doldurmasına izin vermek genellikle kötüdür (ve onlarla başa çıkmanın en kolay yolu olmamalıydı), çünkü bir arayanın durumun çağırdığı yöntemden beklenen anlama gelip gelmediğini söylemesinin bir yolu yoktur. çağrılan yöntemin kabarcığı uyandırdığı beklenmeyen bir durumu temsil edip etmediği.
supercat, 13.03.2014
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.