Değerin ilettiği parametrelerin değerlerini değiştirmemenin bir nedeni var mı?


9

Bir fonksiyonun gövdesindeki by-value parametrelerinin değerlerini değiştirmeye karşı veya ona karşı nesnel, desteklenebilir yazılım mühendisliği argümanları var mı?

Ekibimde tekrar eden bir tükürük (çoğunlukla iyi eğlenceler), değere göre iletilen parametrelerin değiştirilip değiştirilmeyeceği. Ekibin birkaç üyesi, parametrelere asla atanmaması gerektiği konusunda kararlıdır, böylece fonksiyona başlangıçta iletilen değer her zaman sorgulanabilir. Ben katılmıyorum ve parametreler yöntemi çağıran sözdizimi tarafından başlatılan yerel değişkenler başka bir şey değildir tutun; bir by-value parametresinin orijinal değeri bir yerel değişkenten daha önemliyse, bu değeri açıkça sakladığı bildirilebilir. İkimizin de pozisyonumuza çok iyi destek verdiğinden emin değilim.

Bu çözülemez bir dini çatışma mıdır, yoksa her iki yönde de iyi, nesnel yazılım mühendisliği nedenleri var mı?

Not: İlke sorunu, belirli bir dilin uygulama detaylarına bakılmaksızın kalır. Örneğin, argümanlar listesinin her zaman dinamik olduğu JavaScript'te, parametreler argumentsnesneden yerel değişken başlatma için sözdizimsel şeker olarak kabul edilebilir . Yine de, parametre tarafından tanımlanan tanımlayıcılara "özel" olarak bakılabilir, çünkü yine de bilginin arayandan çağırana geçişini yakalarlar.


Hala dile özgüdür; dilde agnostik olduğunu iddia ederek "benim (favori dilimin) bakış açısından öyle" geçersiz bir argüman. Dile özgü olmasının ikinci bir nedeni de, tüm diller için evrensel cevabı olmayan bir sorunun her dilin kültürüne ve normuna tabi olmasıdır; bu durumda, dile özgü farklı normlar bu soruya farklı cevaplar verir.
rwong

Ekip üyelerinizin size öğretmeye çalıştığı ilke "tek değişken, tek amaç" tır. Ne yazık ki, her iki şekilde de kesin kanıt bulamayacaksınız. Değer için ne kadar başka bir amaç için bir parametre değişkenini seçtiğimi hatırlamıyorum, ne de düşündüğümü hatırlamıyorum. İyi bir fikir olabileceği aklıma hiç gelmedi ve hala öyle olduğunu düşünmüyorum.
Robert Harvey

Bu daha önce sorulmuş olması gerektiğini düşündüm, ama bulabildiğim tek dupe bu eski SO sorudur .
Doc Brown

3
İşlevsel dil tasarımcılarının “izin” atamalarının hataya daha az eğilimli olduğunu düşünmesi gibi, bir dilin argüman mutasyonunu yasaklaması için daha az hataya yatkın olarak kabul edilir. Herkesin bu varsayımı bir çalışma kullanarak kanıtladığından şüpheliyim.
Frank Hileman

Yanıtlar:


15

Ben katılmıyorum ve parametreleri yöntem çağırma sözdizimi tarafından başlatılan yerel değişkenlerden başka bir şey değildir tutun

Üçüncü bir konum benimsiyorum: parametreler yerel değişkenler gibi: her ikisi de varsayılan olarak değişmez olarak ele alınmalıdır. Bu nedenle değişkenler bir kez atanır ve yalnızca değiştirilir, okunmaz. Döngüler söz konusu olduğunda for each (x in ...), değişken her bir yineleme bağlamında değişmezdir. Bunun nedenleri:

  1. kodun "kafamda çalıştırılmasını" kolaylaştırır,
  2. değişkenler için daha açıklayıcı adlara izin verir.

Atanan ve sonra değişmeyen değişkenler bir grup ile karşı karşıya, ben bu değişkenlerin her birinin geçerli değerini hatırlamaya çalışmak yerine, kod okumaya odaklanabilirsiniz.

Aynı yöntemle karşılaştığımızda, bu kez daha az değişkenle, ancak her zaman değeri değiştiren, şimdi bu değişkenlerin mevcut durumunu hatırlamak zorundayım ve kodun ne yaptığını çalışmak zorundayım.

Deneyimlerime göre, ilki zayıf beynimde çok daha kolay. Diğer, zeki, benden halk bu sorunu olmayabilir, ama bana yardımcı olur.

Diğer noktaya gelince:

double Foo(double r)
{
    r = r * r;
    r = Math.Pi * r;
    return r;
}

karşı

double Foo(int r)
{
    var rSquared = r * r;
    var area = Math.Pi * rSquared;
    return area;
} 

Onaylanmış örnekler, ancak bence değişken isimler nedeniyle ikinci örnekte neler olduğu çok daha açık: okuyucuya rilk örnekte olduğundan çok daha fazla bilgi aktarıyorlar .


"yerel değişkenler .... varsayılan olarak değişmez olarak ele alınmalıdır." - Ne?
whatsisname

1
forDeğişkenleri olmayan döngüler çalıştırmak oldukça zordur . Fonksiyondaki değişkenin kapsüllenmesi sizin için yeterli değil mi? Yalnızca bir işlevde değişkenlerinizi takip etmekte sorun yaşıyorsanız, belki de işlevleriniz çok uzundur.
Robert Harvey

@RobertHarvey for (const auto thing : things)bir for döngüsüdür ve tanıttığı değişken (yerel olarak) değişmezdir. for i, thing in enumerate(things):Ayrıca yerliler mutasyona
uğramaz

3
Bu IMHO genel olarak çok iyi bir zihinsel model. Bununla birlikte, eklemek istediğim bir şey: bir değişkeni birden fazla adımda başlatmak ve daha sonra değişmez olarak kabul etmek genellikle kabul edilebilir. Bu, burada sunulan genel stratejiye karşı değildir, sadece bunu tam anlamıyla takip etmeye karşıdır.
Doc Brown

3
Vay be, bu yorumları okuyarak, buradaki birçok insanın fonksiyonel paradigmayı hiç incelemediğini görebiliyorum.
Joshua Jones

4

Bu çözülemez bir dini çatışma mıdır, yoksa her iki yönde de iyi, nesnel yazılım mühendisliği nedenleri var mı?

Bu gerçekten hoşuma giden bir şey (iyi yazılmış) C ++: ne olacağını görebilirsiniz. const string& x1sabit bir referanstır, string x2bir kopyadır ve const string x3sabit bir kopyadır. Ben biliyorum işlevinde ne olacağı. x2 olacak o olmasaydı, bu const olmayan yapmak için hiçbir neden olacağını, çünkü değiştirilebilir.

Eğer izin veren bir diliniz varsa , parametrelerle ne yapmak istediğinizi açıklayın. Bu, ilgili herkes için en iyi seçim olmalıdır.

Diliniz buna izin vermiyorsa, korkarım gümüş kurşun çözümü yoktur. Her ikisi de mümkündür. Tek rehber en az sürpriz ilkesidir. Tek bir yaklaşım kullanın ve kod tabanınız boyunca onunla birlikte gidin, karıştırmayın.


Başka bir iyi şey şudur int f(const T x)ve int f(T x)sadece işlev bedeninde farklıdır.
Deduplicator

3
const int xSadece net x yapmak gibi bir parametreye sahip bir C ++ fonksiyonu içeride değişmez mi? Bana çok garip bir tarz gibi geliyor.
Doc Brown

@DocBrown Her iki stili de değerlendirmiyorum, sadece parametrelerin değiştirilmemesi gerektiğini düşünen birinin derleyiciyi garanti edebileceğini ve değiştirmenin iyi olduğunu düşünen birinin de bunu yapabileceğini söylüyorum. Her iki niyet de dilin kendisi aracılığıyla açıkça iletilebilir ve bu, her iki şekilde de garanti edemeyen bir dil üzerinde ve keyfi yönergelere güvenmeniz ve herkesin bunları okumasını ve bunlara uymasını ummanız gereken büyük bir avantajdır.
nvoigt

@nvoigt: Birisi bir ("by-value") işlev parametresini değiştirmeyi tercih constederse, onu engellerse parametre listesinden uzaklaşacaktır. Bu yüzden soruyu cevapladığını sanmıyorum.
Doc Brown

@DocBrown O zaman artık const değil. Const olsun ya da olmasın önemli değil, önemli olan, dilin şüphesiz geliştiriciyle iletişim kurmanın bir yolunu içermesidir . Benim cevabım, önemli değil, açıkça ifade ettiğiniz sürece , C ++ 'nın kolaylaştığı, diğerleri olmayabilir ve kurallara ihtiyacınız var.
nvoigt

1

Evet, bu "dini bir çatışma" dır, ancak Tanrı'nın (bildiğim kadarıyla) programları okumaması, kişisel yargıya dönüşen okunabilirlik çatışmasına indirgenmiştir. Ve her iki şekilde de kesinlikle yaptım ve yapıldığını gördüm. Örneğin,

void propagate (OBJECT * nesnesi, çift t0, çift dt) {
  çift ​​t = t0; / * değerini değiştirmemek için t0'ın yerel kopyası * /
  while (her neyse) {
    timestep_the_object (...);
    t + = dt; }
  dönüş; }

Yani burada, sadece t0 argüman adı nedeniyle , değerini değiştirmemeyi tercih ederim. Ancak bunun yerine, yalnızca bu argüman adını tNow veya bunun gibi bir şeyle değiştirdik . Sonra yerel bir kopya hakkında çok daha fazla unutmuş ve sadece tNow + = dt yazmak ; bu son ifade için.

Ama tam tersine, programın yazıldığı istemcinin bu kodu okuyan ve üzerinde çalışan çok az deneyime sahip yeni programcılar kiralamak üzere olduğunu bildiğimi varsayalım. Sonra zihinleri tüm iş mantığını sindirmeye çalışmakla meşgulken, onları referansa göre değere göre karıştırmak konusunda endişelenirim. Yani bu tür bir durumda, benim için aşağı yukarı okunabilir olup olmadığına bakılmaksızın değiştirilecek herhangi bir argümanın yerel bir kopyasını her zaman beyan ederim.

Bu tarz stil sorularının cevapları deneyimle ortaya çıkar ve nadiren kanonik bir dini cevaba sahiptir. Bire bir yanıt olduğunu düşünen (ve bunu bildiğini :) düşünen herkes muhtemelen biraz daha deneyime ihtiyaç duyar.

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.