it-swarm.dev

Üçlü operatör zararlı mıdır?

Ö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?

82
fredoverflow

Üç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.

236
user8685

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.

50
mipadi

Ne zaman?: Uygun

  • Kodunuzu daha kısa ve okunaklı hale getirdiğinde.

ve ne zaman değil?

  • Kodunuzu okunamaz hale getirdiğinde.
  • Sadece kodu korumak zorunda olan kişiyi değil, ReSharper gibi bir yeniden düzenleme aracını memnun etmek için yapıyorsanız

Üçlü ifadenin içinde herhangi bir mantık veya işlev çağrınız varsa, bakmayı korkunç hale getirirsiniz.

24
realworldcoder

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;
23
Benjol

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)

13
Henno Brandsma

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:

  1. x bir sabittir ve bu nedenle hata ekleme şansı çok daha azdır ve potansiyel olarak ikincisinin asla olmayacağı şekilde optimize edilebilir.
  2. Tür ifade tarafından açıkça belirtilir, böylece derleyici 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.

7
Rei Miyasaka

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.

7
the Tin Man

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.

3
Uwe Keim

İş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?

2
hapybrian

Ş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.

2
Norman Ramsey
  1. "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.

  2. Üç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.

2
user8865

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.

2
Mike Dunlavey

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. :-)

2
Zan Lynx

Söyleyebilir miyim? Üçlü operasyonun bu özel uygulamasını bulmayı başaramıyorum kötü:

  1. gerçekleştirdiği işlem oldukça önemsizdir ve bir kez zorlandığınızda, bazı hatalar çıkacaktır;
  2. yaptığı şey işlev adında açıkça belirtilmiştir;
  3. çok açık bir şey için> 1 satır almak ve bu kadar açık bir şekilde geliştirilmeyecektir (sihirli bir medyan algoritması şimdiye kadar tespit edilmemişse).

Lütfen merhamet et, ünüm zaten çok acınacak durumda.

1
cbrandolino

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.

1
user11134

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.

1
Andy Lester

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.

1
Tangurena

Üç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.

1
leed25d

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.

0
guiman

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.

0
Axeman

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 ...)

0
Jerry Coffin

Ne zaman?: Uygun ve ne zaman değil?

  • Bir performans kazancı elde etmiyorsanız, kullanmayın; kodunuzun okunabilirliğini etkiler.
  • Bir kez kullanın ve yuvalamayın.
  • Hata ayıklamak daha zor.

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.

0
Amir Rezaei

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ı

0
jk.