Örneğin, bu tek astarı tercih eder misiniz
int median(int a, int b, int c) {
return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
veya birden çok iade ifadesi içeren bir if/else çözümü?
Ne zaman ?:
uygun ve ne zaman değil? Yeni başlayanlara öğretilmeli veya gizlenmeli mi?
Üçlü operatör kötülük mü?
Hayır, bu bir nimet.
Ne zaman?: Uygun?
Çok basit bir şey olduğunda, çok fazla satır kaybetmek istemezsiniz.
ve ne zaman değil?
Kodun okunabilirliği ve netliği düştüğünde ve yetersiz dikkat yoluyla bir hata potansiyeli arttığında, örneğin, tıpkı örneğinizde olduğu gibi, birçok zincirleme operatör ile.
Turnusol testi, kodunuzun uzun vadede kolayca okunabilir ve korunabilir olduğundan şüphe etmeye başladığınız zamandır. Öyleyse yapma.
Bence dürüst olmayan üçlü operatör (yani, sadece bir kez kullanıldığı bir ifade) iyi, ama birden fazla yuvalama, okumak biraz zor olur.
Ne zaman?: Uygun
ve ne zaman değil?
Üçlü ifadenin içinde herhangi bir mantık veya işlev çağrınız varsa, bakmayı korkunç hale getirirsiniz.
Hiç kimsenin işaret etmediği bir fark, eğer başka bir değer döndüremezse, üçlü operatör ise.
F # 'dan gelince, bazen desen eşleşmesini taklit etmek için üçlü operatörü kullanmayı seviyorum.
match val with
| A -> 1
| B -> 3
| _ -> 0
vs
return val == A ? 1 :
val == B ? 3 :
0;
Geçerli bir kullanım örneği (IMHO):
printf("Success in %d %s\n", nr_of_tries, (nr_of_tries == 1 ? "try" : "tries"));
Bu, 2 ayrı yazdırma ifadesine sahip olmaktan daha okunabilir kod sağlar. Yuvalanmış örnekler aşağıdakilere bağlıdır: (anlaşılabilir mi? Evet: hayır)
Kesinlikle kötü değil. Aslında, saf ve eğer öyleyse değilse.
Haskell, F #, ML vb. Gibi işlevsel dillerde, kötülük olarak kabul edilen if-then-else ifadeleri.
Bunun nedeni, zorunlu bir if-then-else ifadesi gibi herhangi bir "eylemin", değişken bir bildirimi tanımından ayırmanızı gerektirmesi ve işlevinize state eklemesidir.
Örneğin, aşağıdaki kodda:
const var x = n % 3 == 1
? Parity.Even
: Parity.Odd;
vs.
Parity x;
if (n % 3 == 1)
x = Parity.Even;
else
x = Parity.Odd;
İlki daha kısa olmanın yanı sıra iki avantajı var:
x
bir sabittir ve bu nedenle hata ekleme şansı çok daha azdır ve potansiyel olarak ikincisinin asla olmayacağı şekilde optimize edilebilir.x
türünün Parity
türünde olması gerektiğini zahmetsizce çıkarabilir.Kafa karıştırıcı bir şekilde, işlevsel dillerde üçlü operatör genellikle if-then-else olarak adlandırılır. Haskell'de x = if n mod 3 == 1 then Odd else Even
.
Bu ifade gözlerimi incitiyor; Ekibimde onu kullanamayan herhangi bir geliştiriciyi kirlettim, çünkü sürdürülemez.
Üçlü operatörler iyi kullanıldıklarında kötü değildir. Tek sıra bile olmaları gerekmiyor; İyi biçimlendirilmiş uzun bir tane çok açık ve anlaşılması kolay olabilir:
return
( 'a' == $s ) ? 1
: ( 'b' == $s ) ? 2
: ( 'c' == $s ) ? 3
: 4;
Ben/then/else zinciri eşdeğer daha iyi gibi:
if ( 'a' == $s ) {
$retval = 1;
}
elsif ( 'b' == $s ) {
$retval = 2;
}
elsif ( 'c' == $s ) {
$retval = 3;
}
else {
$retval = 4;
}
return $retval;
Bunları yeniden biçimlendireceğim:
if ( 'a' == $s ) { $retval = 1; }
elsif ( 'b' == $s ) { $retval = 2; }
elsif ( 'c' == $s ) { $retval = 3; }
else { $retval = 4; }
return $retval;
koşullar ve atamalar kolay hizalamaya izin veriyorsa. Yine de üçlü versiyonu tercih ediyorum çünkü daha kısa ve koşullar ve ödevler arasında çok fazla gürültü yok.
ReSharper VS.NET'te bazen if...else
ile ?:
Şebeke.
Görünüşe göre ReSharper sadece koşullar/bloklar belirli bir karmaşıklık seviyesinin altındaysa önerir, aksi takdirde if...else
.
İşte is kötülüğünün bir örneği:
oldValue = newValue >= 0 ? newValue : oldValue;
Kafa karıştırıcı ve savurgan. Derleyici ikinci ifadeyi optimize edebilir (oldValue = oldValue), ancak kodlayıcı bunu neden ilk etapta yaptı?
Başka bir doozy:
thingie = otherThingie != null ? otherThingie : null;
Bazı insanlar sadece kodlayıcı değildir ...
Greg, if ifadesinin 'gürültülü' olduğu anlamına gelir. Gürültüyle yazarsanız. Ama aynı şekilde şöyle yazılabilir:
if ('a' == $s) return 1;
if ('b' == $s) return 2;
if ('c' == $s) return 3;
return 4;
Bu üçlüden daha gürültülü değil. Üçlü kısayolların olup olmadığını merak ediyorum; tüm ifadeler değerlendirilir mi?
Şeytan olmaktan çok, üçlü operatör bir nimettir.
nested ifadesinde karar vermek istediğinizde çok kullanışlıdır. Klasik örnek bir işlev çağrısıdır:
printf("I see %d evil construct%s in this program\n", n, n == 1 ? "" : "s");
Özel örneğinizde, üçlü _ neredeyse $ zordur, çünkü return
altındaki en üst düzey ifadedir. return
anahtar kelimesinden başka bir şeyi çoğaltmadan koşullu ifadeyi ifade düzeyine yükseltebilirsiniz.
N.B. Hiçbir şey medyan için bu özel algoritmayı okumayı kolaylaştıramaz.
"Kötülük" argümanları bir yana, tecrübelerime göre, bir programcının üçlü operatörü kullanması ve tüm kod tabanının okunması, izlenmesi ve sürdürülmesi zor olması (açık bir şekilde belgelenmemişse) arasında yüksek bir ilişki buldum. Bir programcı, kodunu anlayabilen birinden birkaç 1-2 karakter satırı kaydetmekle daha fazla ilgiliyse, üçlü ifadeyi anlayan küçük bir karışıklık genellikle buzdağının görünen kısmıdır.
Üçlü operatörler sinekleri çeker gibi sihirli sayılar çeker.
Belirli bir sorunu çözmek için bir Açık Kaynak kütüphanesi arıyordum ve orijinal kütüphanenin üçlü operatörleri gibi kodları söz konusu kütüphane için bir adayda görmüşsem, uyarı zilleri kafamda çalmaya başlayacak ve devam etmeyi düşünmeye başlayacaktım borç almak için başka bir projeye.
Evil? Bak, sadece farklılar.
if
bir ifadedir. (test ? a : b)
bir ifadedir. Aynı şey değiller.
Değerleri ifade etmek için ifadeler mevcuttur. İşlemleri gerçekleştirmek için ifadeler var. İfadeler ifadelerin içinde görünebilir, ancak tam tersi değil. Böylece bir ifadedeki terimler veya bir yönteme yönelik argümanlar gibi diğer ifadelerde üçlü ifadeler kullanabilirsiniz. zorunda değilsiniz, ama sen eğer yapabilirsen. Bunda yanlış bir şey yok. Bazı insanlar bunun kötü olduğunu söyleyebilir, ama bu onların görüşü.
Üçlü ifadenin bir değeri, hem doğru hem de yanlış durumları ele almanızdır. if
ifadeleri yok.
Okunabilirlik konusunda endişeleriniz varsa, bunları okunabilir biçimde biçimlendirebilirsiniz.
Her nasılsa "kötülük" programlama kelime içine sızdı. İlk kimin düşürdüğünü bilmek isterdim. (Aslında, bir şüphelim var - o MIT'de.) Sadece insanların zevk ve isim çağrısı değil, bu alanda değer yargıları için objektif nedenlerimiz olmasını tercih ederdim.
Bu, if/else kombinasyonu kadar güzel görünecek şekilde yeniden biçimlendirilebilir:
int median(int a, int b, int c)
{
return
(a<b)
?
(b<c)
? b
:
(a<c)
? c
: a
:
(a<c)
? a
:
(b<c)
? c
: b;
}
Ama sorun şu ki, girintiyi gerçekten olacakları temsil etme hakkım olup olmadığından emin değilim. :-)
Söyleyebilir miyim? Üçlü operasyonun bu özel uygulamasını bulmayı başaramıyorum kötü:
Lütfen merhamet et, ünüm zaten çok acınacak durumda.
Kodunuzu çirkin yapan her şey kötüdür.
Kodunuzu daha temiz hale getirmek için üçlü kullanırsanız, mutlaka kullanın. Bazen php gibi, satır içi ikameler yapmak harika, örn.
"Hello ".($Male?"Mr":"Ms")." $Name
Bu, birkaç satır kazandırır ve oldukça açıktır, ancak örneğinizin net olması için en az daha iyi biçimlendirmeye ihtiyacı vardır ve üçlü çok satırlı için gerçekten iyi değildir, eğer if/else komutunu da kullanabilirsiniz.
En büyük kazanç: Tek bir eylem hedefi olduğunu göstermek.
if ( $is_whatever )
$foo = 'A';
else
$foo = 'B';
İzleyebileceğiniz iki kod yolu vardır ve okuyucu hangi iki değişkenin ayarlandığını görmek için dikkatlice okumalıdır. Bu durumda, bu sadece bir değişkendir, ancak okuyucunun bunu anlayacak daha çok şeyi vardır. Sonuçta, bu olabilirdi:
if ( $is_whatever )
$foo = 'A';
else
$bar = 'B';
Üçlü operatör ile, sadece bir değişkenin ayarlandığı açıktır.
$foo = $is_whatever ? 'A' : 'B';
En düşük seviyede, DRY (Kendinizi Tekrar Etmeyin) ilkesi en temelidir. $foo
sadece bir kez yapın.
Bir yeri var. Geliştiricilerin beceri seviyelerinin korkunçtan büyücüye kadar değiştiği birçok şirkette çalıştım. Kodun korunması gerektiğinden ve sonsuza kadar orada olmayacağımdan, oraya ait gibi görünmesi için bir şeyler yazmaya çalışıyorum (baş harflerle ilgili yorumlara bakmadan, yapabilmeniz için son derece nadirdir) nerede değişiklikler yaptığımı görmek için üzerinde çalıştığım koda bakın) ve benden daha az beceriye sahip birinin bunu koruyabildiğini.
Üçlü operatör nitziffic ve serin görünüyor olsa da, benim deneyimim kod satırının sürdürülmesinin neredeyse imkansız olacağı. Mevcut işverenimde, yaklaşık 20 yıldır nakliye yapan ürünlerimiz var. Bu örneği hiçbir yerde kullanmam.
Üçlü operatörün kötü olduğunu düşünmüyorum.
İşte beni güldüren bir yaka. Birçoğu (10+) için C programcısıydım ve 1990'ların sonunda web tabanlı uygulama programlamasına geçtim. Bir web programcısı olarak, yakında PHP rastladı. PHP program sonunda bir çizgi izledi bir hata vardı) Üçlü işleç ile PHP üçlü işleç soldan sağa, ancak C üçlü işleç (ben alışkınım) sağdan sola ilişkilendirilir.
Ne zaman uygundur, ne zaman değildir?
Bence homojen bir grup insan için gelişirken sorun yoktur, ancak farklı seviyelerde çalışan insanlarla uğraşmak zorunda kaldığınızda, bu tür onelinerlerin sadece koda daha fazla karmaşıklık getirdiği söylenebilir. Yani, bu konudaki politikam: kısa kod yerine açık ve dont açıklamayın ve 123123 kez açıklayın.
Yeni başlayanlara öğretilmeli veya gizlenmeli mi?
Yeni başlayanlara öğretilmemeliyim, daha sonra ihtiyaç duyulduğunda çözmelerini tercih etmeliyim, bu yüzden sadece bir ihtiyaç duyduğunuzda değil, sadece gerekli olduğunda kullanılacaktır.
Düzenli olarak 600-1200 satırlık yöntemler yazan bir dükkan olmamalı bana bir üçlünün "anlaşılması zor" olduğunu söyler. Düzenli olarak kod koşullarını değerlendirmek için beş koşul sağlayan tüm dükkanlar olmamalıdır bir üçlüdeki somut olarak özetlenmiş koşulların "okunması zor" olduğunu söyler.
IMO, operatörün kendisi kötü değildir, ancak C (ve C++) için kullanılan sözdizimi aşırı derecede kısadır. IMO, ALGOL 60 daha iyisini yaptı, bu yüzden böyle bir şey:
A = x == y ? B : C;
daha çok şöyle görünür (ancak genel olarak C benzeri sözdizimine bağlı kalır):
A = if (x==y) B else C;
Bununla bile, aşırı derin yuvalama, okunabilirlikle ilgili sorunlara yol açabilir, ancak en azından A) programlama yapan herkes basit bir çözüm bulabilir ve B) bunun daha derin yuvalamayı oldukça kolay bir şekilde halledebileceğini anlayan insanlar. OTOH, ayrıca LISP'de (örneğin) bir cond
'ın üçlü bir ifadeye benzediğini - bir ifade kümesi değil, tek bir ifadenin bir değer verdiğini (sonra tekrar, çoğu LISP böyle ...)
Ne zaman?: Uygun ve ne zaman değil?
Yeni başlayanlara öğretilmeli veya gizlenmeli mi?
Önemli değil, ama bir “yeni başlayanın” öğrenmesi için çok karmaşık olmadığı için kasıtlı olarak gizlenmemelidir.
Eğer ... o zaman ... başkası durumu vurgulama eğilimindedir ve bu nedenle koşullu olarak yapılan operasyonları vurgulamaz.
üçlü operatör tam tersidir, durumu gizleme eğilimindedir ve bu nedenle yapılan işlem koşulun kendisinden daha önemli olduğunda yararlıdır.
Bazı dillerde, biri bir ifade diğeri de bir ifade olması nedeniyle birbirinin yerine kullanılamayacakları küçük teknik eleyip sıkışma vardır. C++ 'ta koşullu koşulların başlatılması