Os.Exit () ve panic () ne zaman kullanılır?


97

Birisi arasındaki temel farklılıkları açıklayabilir misiniz os.Exit()ve panic()onlar Git pratikte nasıl kullanıldığını?


11
Gelecekte Go kodunun okunmasına yardımcı olacağını umduğumuz bir yorum: Birçok örnek kodda panic, yalnızca anlaşılması kolay olduğu için hata durumunda çıkmak için kullanılır ve diğer paketleri içe aktarmayı ortadan kaldırır. Bu , iyi ya da deyimsel pratik olduğu anlamına gelmez! . Bu sadece yer tasarrufu sağlayan bir cihaz, örneğin kod. Çok özel durumlar paniciçin IRL rezervi .
Intermernet

2
Hm..good) özellikle "IRL" kısaltması - benim için yeni :) Paniğin paket içe aktarmayı nasıl ortadan kaldırdığını açıklayabilir misiniz?
Timur Fayzrakhmanov

5
panicbir yerleşiktir. İşletim sistemine bir hata kodu döndüren os.Exit, log.Fatalvb. Gibi bir şey kullanmanız önerilir (duruma bağlı olarak) (mümkünse her zaman önerilir). Bunların hepsi bir paketi içe aktarmayı ve dolayısıyla örnek kodu "karıştırmayı" içerir. Örnek kod her zaman yalnızca belirli bir soruna çözüm göstermek için alınmalıdır. Kodda, uygun şekilde gösterildiğinde kodu daha karmaşık hale getiren ve bu nedenle verilen cevabın açıklamasından uzaklaşan başka sorunlar olabilir. YMMV.
Intermernet

1
Tamam, anladım!) Çok teşekkürler)
Sözlüğüm

2
NP, yardım için mutlu ve sizin acronymic sözlüğü :-) artırmak için
Intermernet

Yanıtlar:


87

Her şeyden önce, bir "uygulamada nasıl kullanıldığını" sorum var zaman, başlamak için iyi bir yol olduğunu arama Git kaynak kodunu (veya herhangi yeterince büyük Git kod tabanını, gerçekten) ve paket belgeler cevaplar için.

Şimdi os.Exitve panicoldukça farklı. panicprogram veya parçası kurtarılamaz bir duruma ulaştığında kullanılır.

Tüm panicbu sınırların dışında bir dilim dizine veya bir tür belirtilme başarısız gibi çalışma zamanı hataları için dolaylı olarak da dahil olmak üzere, adı, hemen çalışmakta olan işlevi durur ve yol boyunca herhangi bir ertelenmiş işlevi çalıştıran, goroutine yığınını dinlenmek başlar. Bu çözülme, gorutinin yığınının tepesine ulaşırsa, program ölür.

os.Exitprogramı kurtarma olasılığı olmadan veya ertelenmiş bir temizleme bildirimi çalıştırmadan hemen iptal etmeniz gerektiğinde ve ayrıca bir hata kodu (diğer programların ne olduğunu bildirmek için kullanabileceği) döndürmeniz gerektiğinde kullanılır. Bu, testlerden biri başarısız olduktan sonra diğerinin de başarısız olacağını zaten bildiğiniz zaman testler için kullanışlıdır, bu yüzden şimdi çıksanız iyi olur. Bu, programınız yapması gereken her şeyi yaptığında ve şimdi sadece çıkması gerektiğinde, yani bir yardım mesajı yazdırdıktan sonra da kullanılabilir.

Çoğu zaman kullanmayacaksınız panic( errorbunun yerine bir iade etmelisiniz ) ve os.Exittestlerdeki bazı durumlar dışında ve hızlı program sonlandırması için neredeyse hiç ihtiyaç duymazsınız.


9
"Bu, testlerden biri başarısız olduktan sonra diğerinin de başarısız olacağını zaten bildiğiniz zaman testlerde kullanışlıdır ..." Bu, bağımlı testlerin anti-modelini test etmek gibi kokuyor. İyi yazılmış bir test paketinde her test bağımsızdır; Herhangi bir testin sonucu, başka bir testin sonucunu asla belirlememelidir.
gotgenes

1
@gotgenes Mutlaka değil. Belirli bir fonksiyonun sıfır olmayan bir yapı döndürdüğüne dair bir testim varsa ve bu test başarısız olursa, yapının değerlerini inceleyen tüm testlerin de başarısız olmasını bekleyebilirim. Bağımlı olan koddur, testler değil. (Bununla birlikte, exitbu durumda kullanmayacağımı söyledi, sadece büyük bir başarısız iddia yığını bekliyordum.)
David Moles

85

Her şeyden önce, os.Exit()programdan normal olarak hatasız çıkmak için kullanılabilir ve panik yapmaz, bu yüzden bu önemli bir ayrımdır. Bir diğeri ise, bir yerde paniğin yakalanması ve görmezden gelinmesi veya kullanılarak kaydedilebilmesidir recover.

Ancak hatalı bir çıkış kodundan bahsediyorsak, diyelim ki:

Bir panicşeyler korkunç derecede ters gittiğinde, muhtemelen üretime geçmeden önce yakalanması gereken bir programcı hatası olduğunda kullanın. Yığını yazdırmasının nedeni budur.

Aşağıdakileri os.Exit(errorCode)yapmak istiyorsanız veya bunun gibi bir şey kullanın :

  1. komut dosyası oluşturma amacıyla programın çıkış kodunu kontrol edin.

  2. beklenen bir hatada düzenli bir çıkış istemek (örneğin, kullanıcı girişi hatası).

Yani temelde panik sizin için, kötü bir çıkış kodu kullanıcınız içindir.


Teşekkürler çok yardımcı oldu!)
Timur Fayzrakhmanov

15
"Yani temelde panik sizin için, kötü bir çıkış kodu kullanıcınız içindir." <- Müthiş ipucu
psousa

1
Panik () 'in basit C'deki olağan assert () çağrısıyla bir şekilde ilişkili olduğunu söyleyebilir miyiz? Pekala .. Üretime geçmeden önce her zaman iddia etme çağrısını kaldırdığımı biliyorum, onları yalnızca yeni bir özelliği test ederken etkinleştiriyorum. Demek istediğim, kodumda doğru olması gerektiğini tahmin ettiğim değişmezleri doğrulamak için çoğu zaman assert () kullanıyorum. Panic () için aynı kullanımı görüyor musunuz? :-)
yves Baumes

7

Temel farklar şunlardır:

  1. os.Exit ertelenmiş işlevin yürütülmesini atlar.
  2. İle os.Exitçıkış kodunu belirtebilirsiniz.
  3. panicos.Exitdeğil süre sona eriyor . (Görünüşe göre diğer cevaplar bundan bahsetmiyor.)

Ertelenmiş işlevi yürütmeniz gerekiyorsa, başka seçeneğiniz yoktur panic. (Öte yandan, ertelenmiş işlevin yürütülmesini atlamak istiyorsanız kullanın os.Exit.)

Geçersiz olmayan bir işlev bu şekilde tanımlanmışsa:

  1. işlev çok sayıda dal içerir
  2. tüm şubeler returnveya ile sonlandırılırpanic

O zaman yerine koyamazsınız panic, os.Exitaksi takdirde derleyici "işlevin sonunda eksik dönüş" diyerek programı derlemeyi reddeder. (Go burada çok aptalca, hatta log.Panicbir işlevi sonlandırmıyor.)

Diğer koşullar altında:

  1. panicGerçekten bağlantılı bir şey olduğunda kullanın , örneğin programlama mantığı hatası.
  2. os.ExitBelirtilen çıkış koduyla hemen çıkış istediğinizde kullanın .
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.