Hızlıca "ön koşul" ve "iddia etmek" arasındaki fark nedir?


105

Swift arasındaki precondition(condition: Bool, message: String)ve assert(condition: Bool, message: String)arasındaki fark nedir ?

İkisi de bana aynı görünüyor. Hangi bağlamda birini diğerinin üzerinde kullanmalıyız?

Yanıtlar:


125

asserttest sırasında akıl sağlığı kontrolleri içindir, oysa preconditionolursa, programınızın makul bir şekilde ilerleyemeyeceği anlamına gelen şeylere karşı korunmak içindir.

Örneğin, bir asserthatanız olup olmadığını hızlı bir şekilde bulmak için mantıklı sonuçlara sahip (örneğin bazı sınırlar içinde) bazı hesaplamalara koyabilirsiniz . Ancak, sınır dışı sonuç geçerli olabileceğinden ve kritik olmadığından, bununla birlikte göndermek istemezsiniz, bu nedenle uygulamanızı çökertmemelisiniz (sadece ilerlemeyi bir ilerleme çubuğunda görüntülemek için kullandığınızı varsayalım).

Öte yandan, bir öğe getirilirken bir dizideki bir alt simgenin geçerli olup olmadığının kontrol edilmesi a precondition. İsteğe bağlı olmayan bir değer döndürmesi gerektiğinden , dizi nesnesinin geçersiz bir alt simge istendiğinde gerçekleştirmesi için makul bir sonraki eylem yoktur .

Dokümanlardan tam metin (seçeneği tıklatmayı assertve preconditionXcode'da deneyin ):

Ön koşul

İlerlemek için gerekli bir koşulu kontrol edin.

Sevkıyat kodunda bile programın ilerlemesini engellemesi gereken koşulları tespit etmek için bu işlevi kullanın.

  • Oyun alanlarında ve -Onone yapılarında (Xcode'un Hata Ayıklama yapılandırması için varsayılan): conditionyanlış olarak değerlendirilirse, yazdırmadan sonra hata ayıklanabilir bir durumda program yürütmesini durdurun message.

  • In -O builds (Xcode'un Release konfigürasyonu için varsayılan): conditionfalse olarak değerlendirilirse, program yürütmesini durdurun.

  • In -Ounchecked yapılar conditiondeğerlendirilmez, ancak optimizer bunun olarak değerlendirileceğini varsayabilir true. -Ounchecked yapılarda bu varsayımı karşılayamamak ciddi bir programlama hatasıdır.

İddia

İsteğe bağlı bir mesajla geleneksel C tarzı iddia.

Bu işlevi, test sırasında aktif olan ancak gönderi kodunun performansını etkilemeyen dahili sağlık kontrolleri için kullanın. Sürüm yapılarında geçersiz kullanımı kontrol etmek için; bakın precondition.

  • Oyun alanlarında ve -Onone yapılarında (Xcode'un Hata Ayıklama yapılandırması için varsayılan): conditionyanlış olarak değerlendirilirse, yazdırmadan sonra hata ayıklanabilir bir durumda program yürütmesini durdurun message.

  • In -O derlemeleri (Xcode'un Release konfigürasyonu için varsayılan) conditiondeğerlendirilmez ve hiçbir etkisi yoktur.

  • In -Ounchecked yapılar conditiondeğerlendirilmez, ancak optimizer bunun olarak değerlendirileceğini varsayabilir true. -Ounchecked yapılarda bu varsayımı karşılayamamak ciddi bir programlama hatasıdır.


2
"Ancak bununla göndermek istemezsiniz, çünkü sınır dışı sonuç geçerli olabilir ve kritik olmayabilir , bu nedenle uygulamanızı çökertmemelisiniz" bu benim için çok belirsiz. Lütfen tam bir örnek verebilir misiniz? Belki bir kod.
Honey

2
Sorunuza yanıt verirken, ben yazarken ve test ederken yapımda olmaması gereken şeyleri yakalamak için kişisel olarak iddialar kullanıyorum. JSON'un data["name"]olmadığı yerde JSON okuyan bir koruma ifadesi hayal edin , ancak olması gerekir. Korumanın içinde bir iddiaya sahip olmak..else {} çökerek ve beni soruna getirerek hatamı yakalamama yardımcı olur. Benzer şekilde, bu kod üretimde olsaydı, iddia programı çökertmezdi ve kullandığım yedekleme kodu ( return nil) devralırdı.
Alec O

1
Dizini kontrol edip tüm uygulamayı çökertmek yerine hiçbir şey yapmamanız gerekmez mi?
Iulian Onofrei

Evet, dizini kontrol etmelisiniz, ancak bazen herkes kayar ve iddiaları kullanmak, unuttuğunuzda dizini kontrol etmiş olmanız gerektiğini anlamanıza yardımcı olur.
Victor Engel

"Ancak, sınır dışı sonuç geçerli olabileceği ve kritik olmadığı için uygulamanızı çökertmemesi gerektiğinden, bununla göndermek istemezsiniz". Uygulamanızı istediğiniz kadar iddiayla gönderebilirsiniz. Swift, yayınlama uygulamasındaki iddia bloğundaki koşullarınızı değerlendirmeyecek
Akshansh Thakur

90

Swift iddialarını buldum - eksik kılavuz yardımcı olacak

                        debug   release   release
function                -Onone  -O       -Ounchecked
assert()                YES     NO        NO
assertionFailure()      YES     NO        NO**
precondition()          YES     YES       NO
preconditionFailure()   YES     YES       YES**
fatalError()*           YES     YES       YES

Ve Swift Evolution hakkındaki ilginç tartışmalardan

- assert: dahili hatalar için kendi kodunuzu kontrol etme

- ön koşul: müşterilerinizin size geçerli argümanlar verdiğini kontrol etmek için.

Ayrıca, ne kullanacağınız konusunda dikkatli olmanız gerekir, bkz. İddia , Hata ve Optimizasyon Düzeyi


Kendi kodunuz ve müşteriniz arasındaki farkı biraz daha açabilir misiniz? İstemciye gelince, bir String'in beklendiği yerde sayı eklemek gibi mi demek istiyorsunuz? Bunun basit bir hata işleme ile tedavi edilmesi gerekmez mi?
Honey

@Honey Sanırım ağ API çağrısından veya müşterinin kendi eklentilerinden gelen argümanlar / sonuçlar hakkında kastettiğini düşünüyorum.
Chen Li Yong

İstemci, kodunuzu kullanan biri olabilir, örneğin bir kitaplık yazdığınızı ve bir programcının geçersiz verileri ilettiğini söyleyin. Ciddi bir programlama hatası olarak düşünülebileceğinden, zarafetle devam etmek istemezsiniz. Muhtemelen geçersiz ağ API verilerinde asla çökmemelisiniz çünkü bu, kullanıcı için çok yararsızdır.
bompf

@ onmyway133: Xcode QuickHelp, ben düşünüyorum precondition()ve preconditionFailure()vardır aynı davranışları sahip . Bu işlevler arasındaki fark şudur: preconditioniçeride bir koşula ihtiyaç duyarken, preconditionFailuresadece dışarı atılır.
nahung89

13

preconditionUygulamanızı gemi zaman size böylece sürüm modunda aktiftir ve önkoşul uygulaması sona erer başarısız oldu. Assertvarsayılan olarak sadece hata ayıklama modunda çalışır.

NSHipster'da ne zaman kullanılacağına dair bu harika açıklamayı buldum:

İddialar, klasik mantıktan ödünç alınmış bir kavramdır. Mantıkta iddialar, bir ispat içindeki önermeler hakkındaki ifadelerdir. Programlamada iddialar, programcının beyan edildikleri yerde uygulama hakkında yaptığı varsayımları ifade eder.

Bir yöntem veya işlevin yürütülmesinin başlangıcında ve sonunda kodun durumuna ilişkin beklentileri tanımlayan ön koşullar ve son koşullar kapasitesinde kullanıldığında, iddialar bir sözleşme oluşturur. Onaylar, belirli ön koşullar başarısız olduğunda yürütmeyi önlemek için çalışma zamanında koşulları zorlamak için de kullanılabilir.


Onaylar, bir derleyici bayrağı kullanılarak etkinleştirilebilir ve devre dışı bırakılabilir; sevk edilen kodda aktif olabilirler.
Pétur Ingi Egilsson

6

ön koşul

func precondition(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

İlerlemek için gerekli bir koşulu kontrol edin.

  1. Sevkıyat kodunda bile programın ilerlemesini engellemesi gereken koşulları tespit etmek için bu işlevi kullanın.
  2. Oyun alanlarında ve -Onone yapılarında (Xcode'un Hata Ayıklama yapılandırması için varsayılan): koşul yanlış olarak değerlendirilirse, mesajı yazdırdıktan sonra hata ayıklanabilir durumda program yürütmeyi durdurun.
  3. In -O derlemeleri (Xcode'un Release yapılandırması için varsayılan): koşul yanlış olarak değerlendirilirse, program yürütmeyi durdurun.
  4. In -Ounchecked yapılarda koşul değerlendirilmez, ancak optimize edici bunun doğru olarak değerlendirileceğini varsayabilir. -Ounchecked yapılarda bu varsayımı karşılayamamak ciddi bir programlama hatasıdır.

iddia etmek

func assert(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

İsteğe bağlı bir mesajla geleneksel C tarzı iddia.

  1. Bu işlevi, test sırasında aktif olan ancak gönderi kodunun performansını etkilemeyen dahili sağlık kontrolleri için kullanın. Sürüm yapılarında geçersiz kullanımı kontrol etmek için; ön koşula bakın.

  2. Oyun alanlarında ve -Onone yapılarında (Xcode'un Hata Ayıklama yapılandırması için varsayılan): koşul yanlış olarak değerlendirilirse, mesajı yazdırdıktan sonra hata ayıklanabilir durumda program yürütmeyi durdurun.

  3. In -O derlemeleri (Xcode'un Release konfigürasyonu için varsayılan), koşul değerlendirilmez ve hiçbir etkisi yoktur
  4. In -Ounchecked yapılarda koşul değerlendirilmez, ancak optimize edici bunun doğru olarak değerlendirileceğini varsayabilir. -Ounchecked yapılarda bu varsayımı karşılayamama ciddi bir programlama hatasıdır

0

Sadece 2 sentimi eklemek istedim. Kodunuza istediğiniz kadar iddia ekleyebilirsiniz. Kodunuzu bu iddialarla gönderebilirsiniz. Swift, bu kod bloklarını üretim uygulamaları için DEĞERLENDİRMEZ. Bunlar yalnızca hata ayıklama modu durumunda değerlendirilir.

Doküman bağlantısı ekleniyor

Ayrıca swift.org'dan resim ekleniyor

görüntü açıklamasını buraya girin

Ayrıca, ön koşullarda durumun böyle olmadığını unutmayın. Ön koşullarla gönderilen kod çökecek ve ön koşullar doğru olarak değerlendirilmezse uygulama sona erecektir.

Kısacası, iddialar hata ayıklama içindir, ancak üretimi etkilemeden gönderilebilir. Onaylar, hata ayıklama modunda değerlendirilecek, ancak üretimde değerlendirilmeyecektir.

Ve

Ön Koşullar, üretim ortamında beklenmedik şeylerin olmamasını sağlamak içindir. Bu koşullar değerlendirilir ve yanlış olarak değerlendirilmeleri durumunda uygulamanızı sonlandırır

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.