İşlev yalnızca değiştirilmemiş parametreyi döndürür, işe yaramaz mı?


15

Bu işlevi çalıştığım projede buldum:

  -- Just returns the text unchanged.
  -- Note: <text> may be nil, function must return nil in that case!
  function Widget:wtr(text)
      return text
  end

Çok üzücü, kodlayıcı artık şirkette çalışmıyor. Neden hiçbir şey yapmayan ama çağrıldığı parametreyi döndüren bir işlev yapsın?

Bu örnekte belirtilmeyen, ancak her durumda genel olarak böyle bir işlevin herhangi bir kullanımı var mı?

Nedeniyle

function aFunction(parameter)
    return parameter
end

Bitiş tarihi

aFunction(parameter) == parameter

Neden böyle bir şey yazayım

aFunction(parameter) == whatIWantToCheck

onun yerine

parameter == whatIWantToCheck

?



13
@gnat Bu nasıl bir kopya?
Kilian Foth

13
Ha? Bu işlev parametresini döndürür - zincirleme geri dönmeyi içerir this.
Kilian Foth

11
@gnat Soru, birisinin neden geri dönüş dışında hiçbir şey yapmayan bir işlev yazmasıdır . Evet, yöntem zincirlemeye izin vermek için belirli nesneleri veya değerleri döndürebilirsiniz, ancak bu onun sorusu değildir. Onun sorusu neden birisi gibi int getParam(int param) { //DO NOTHING return param; } bir şey yazacaktı ki OP'nin işlevini bir yöntem zincirinin dışında bırakabildiğiniz ve tek bir fark yaratmayacağınız için tamamen gereksiz ve gereksiz bir çağrıdır.
ZeroStatic

4
Bu muhtemelen oftopiktir ve lua için geçerli değildir, ancak PHP'de geçerli bir kullanım durumu vardır - eski sürümlerde new Foo()->method();geçerli sözdizimi değildi function with($what) { return $what; }; with(new Foo())->method();ve geçici yapılar olarak kullanılan yapılar .
DCoder

Yanıtlar:


57

Sorunuz, bir sayıya her eklediğinizde aynı değeri geri alırsanız, sıfır sayısının neyin iyi olduğunu sormak gibidir. Bir kimlik işlevi, işlevler için sıfır gibidir. Kendi başına bir tür yararsızdır, ancak zaman zaman bir işlevi parametre olarak alabileceğiniz veya sonuç olarak döndürebileceğiniz yüksek dereceli işlevleri kullanan bir ifadenin parçası olarak bazen yararlıdır. Bu nedenle çoğu işlevsel programlama dili standart kütüphanelerinde idveya identitykütüphanelerinde bulunur.

Başka bir deyişle, kullanışlı bir varsayılan işlev yapar. offset = 0Bir ofset hiçbir şey yapmazsa da, varsayılan bir tamsayı olarak ayarlamak isteyebileceğiniz gibi filterFunction = identity, filtrenin hiçbir şey yapmamasına rağmen, varsayılan bir işlev olarak ayarlanabilmesi kullanışlı olabilir .


Filtre işlevi bir boole değeri döndürmemeli mi? Bu durumda "sıfır" filtre işlevi true değerini döndürür.
Kirill Rakhman

1
@cypressious Bir harita işlevi, o zaman.
sapi

6
Veya bir tasarım konsepti altında yapıştırmak için: Boş nesne kalıbı , fonksiyon baskısı
blgt

@cypressious, bir argüman olarak geçirilen bir yüklemi olurdu içine bir filteryüksek dereceden fonksiyonu. Bir birinci dereceden filterfonksiyonu türü vardır [a] -> [a],
Karl Bielefeldt

Örneğin C # 'da sık sık kullanıyorum.OrderBy(x => x)
CodesInChaos

27

Elbette. Kesinlikle ihtiyacınız olan bir yerden bir şeyler almanıza izin veren harici bir API düşünün, ancak tüm sonuçları isteseniz ve tam olarak depolandığı gibi almak istiyorsanız bile, her sorgu için filtre ölçütleri ve çıktı biçimlendiricileri belirtmeniz gerekir .

Sonra önemsiz bir "her şeyi kabul et" ve verilere ulaşmak için önemsiz bir "değişmeden geri dön" işlevi icat etmeniz gerekir. wtrtam da böyle önemsiz bir sözde biçimlendiricidir. Bu API'yi çok kullanıyorsanız, bir şeyi sorguladığınızda anonim bir işlev oluşturmak yerine bu sahte yardımcı işlevin etrafta olması çok yararlı olabilir. (Bunu çağırarak düşünebilirsiniz identityyerine wtrhemen hiçbir şey yapmaz temizlemek oluyor böylece.)


Henüz duyguyu gerçekten anlamadım, ama bu tam olarak senaryo. Bir süre sonra anlayabilirim, cevabınızı akılda tutarak bu proje üzerinde çalışıyorum. atm bana işe yaramaz görünüyor, ... ham veriyi alsaydım, neden bana ham veriyi tekrar vermek için bir fonksiyon isteyeyim ki, ...
Sempie

3
@Sempie Yine, API bir biçimlendirme işlevi gerektiriyorsa , değiştirilmemiş metni almanın tek yolu, işlevin metne hiçbir şey yapmamasıdır.
Doval

3
Başka bir deyişle: Filtre / format argümanlarının geçirilmesini gerektiren bir fonksiyonunuz varsa ve argüman olarak kesinlikle kullanamıyorsanız null, programın şikayet etmeyi durdurması için 'hiçbir şey' ile filtrelenen boş bir filtre fonksiyonu kullanırsınız.
ZeroStatic

3
@Sempie SQL ile çalıştınız değil mi? Nasıl bir WHEREcümle ekleyip eklemeyeceğinizi biliyor musunuz ? Bu gevşek bir sözdizimsel şeker meselesidir. Esasen bir WHEREcümlenin olmaması, WHEREsadece devam eden ve her şeye izin veren bir cümlenizle tamamen aynıdır . SQL tasarımcılarının, WHEREher şeyi kabul ettiğinde bile, birisini zorlamak yerine bir cümle belirtmenize izin vermemesi , az ya da çok sözdizimsel şekerdir ve size sadece kolaylık sağlamak için bu seçeneği sağladılar. ..
Panzercrisis

5
Çoğu durumda, kodun çağrının gerekip gerekmediğini belirlemesi ve atlaması gerekip gerekmediğini belirlemek yerine, yararlı bir şey yapabilecek veya yapamayan bir sanal yöntemi veya temsilciyi koşulsuz olarak çağırmanın daha hızlı ve daha temiz olduğunu belirtmek gerekir.
supercat

15

Bu sadece bir polimorfizm değil mi?

Qt ile ilgili deneyimlerimden tr()ve wtr()yöntemlerin metninin yerelleştirilmesinde (orada Qt olarak ) kullanılması gerekiyordu Widget.

Yani, değişmeden metni döndürerek bu yöntem sadece diyor ki: Widget does no localization (translation of the text) by default. Override this function to enable your own logic.


1
bunun QT bir şey olduğunun farkında değildim - açıkçası cevap bu.
Corley Brigman

8

Bunun için çok yaygın bir durum 'daha sonra eklenen işlevsellik'tir. Böylece programcı daha sonra bu işlevde bir değişiklik olabileceğini düşündü. Buna parametrenin kendisi olarak değil, bir işlev olarak eriştiğiniz için, bunu küresel olarak kolayca değiştirebilirsiniz. Diyelim ki bir dizininiz var:

function getIndex(index)
    return index
end

ve dizininiz 0'dan başladığından beri her şey yolunda. Daha sonra başka bir yerde bir bileşeni değiştirirseniz, bu bileşen 1'den başlamak için dizininizi çevirmenizi gerektirir. Kodunuzun her yerine yüzlerce dizin + 1 eklemeniz gerekir. Ancak böyle bir yöntemle şunları söyleyin:

 function getIndex(index)
    return index+1
end

ve iyisin. Bunun gibi işlevler hızlı bir şekilde aşırı mühendisliğe yol açabilir, ancak bazı noktalarda çok mantıklıdır!


2
Evet, 's değerinde OP tarafından gönderildi fonksiyonun doctstring olmadığını belirterek olsa değil bu onun durumunda fonksiyonun amacı olduğunu düşündürmektedir.
Mark Amery

6

Bunun gibi saplama işlevleri, tür kalıtım durumlarında yaygındır. Temel sınıf yararlı bir şey yapamaz, ancak türetilmiş sınıflar girdilerle çeşitli şeyler yapabilir. Tüm türetilmiş sınıfları temel sınıfta saplama işlevini sağlar bildirme için var bu isimde bir işlev ve bireysel türetilmiş sınıfları için geçersiz kılmak daha ayrıntılı ve kullanışlı bir şeyle.


5

Ek bir senaryo, python ve C # özelliklerindeki kullanıma benzer, ancak özelliği olmayan dillerde.

Genel olarak, bir şeyi sadece sınıfın bir üyesi olarak ilan edebilirsiniz; diyelim ki 'string' dize olarak. Bu, şu şekilde eriştiğiniz anlamına gelir:

someobject.name

Daha sonra, adın gerçekten nesnede ne olduğuna bağlı olması gerektiğine karar veriyorsunuz. Bu yüzden gerçekten bir işlev olmalı. Hata! Hiç argüman olmasa bile, bu, şimdi ona erişen tüm kodların

someobject.name()

Ancak bu çağrının çok sayıda örneğiniz varsa, bununla ilgili yanlış bir şey yapma şansı oldukça düşüktür - bu değişiklik yapılmayacak bir yerde, o noktaya geldiğinizde program çökecektir.

C # / Python'daki özellikler, bir özellik olarak kullanılan fonksiyonun yerine bir fonksiyonun yerine koymanıza izin verirken, yine de bir özellik gibi, yani değişiklik olmadan erişilmesine izin verir. Önceden planlanmış olmanıza bile gerek yok.

Eğer diliniz buna sahip değilse, önceden plan yapmak zorundasınız, ancak yine de bir şey yapmayan en başından beri bir işlev yaparak insanların daha önce yaptığı gibi destekleyebilirsiniz. Başlangıçta, ilginç bir şey yapmaz ve kaldırılması gerektiği gibi görünür ve bu tür birçok işlev asla değiştirilmez. Ama daha sonra, gerçekten her aradığınızda Widget.wtrbazı özel karakterleri çıkarmanız gerektiğini fark ederseniz , bu önemli değil - zaten bir işlev, bunu ekleyin ve işiniz bitti.

TL; DR Bu, ileride yapılacak değişiklikleri planlamak için akıllıca bir programcı olabilir.


3
Bu yöntem başka bir şeye bağlıysa bu mantıklı olurdu, ama değil. Bu bir özellik, alıcı / ayarlayıcı veya alan değildir. Şu anda hiçbir şey yapmayan bir yöntem. Gelecekteki değişiklikleri planlamanın tek yolu, bu yöntemin mantığının değişmek zorunda kalmasıdır.
Matthew Steeples

1
Bu ... şu anda, bu verileri işlemediğim anlamına gelir, ancak daha sonra, işlemek istiyorsam, bu verilerin her kullanıcısı işlenmiş verileri ücretsiz olarak alır. Aptal örnek: Diyelim ki ekrana dizeler yazdırıyorsunuz ve genellikle yapıyorsunuz print data. Daha sonra, tüm dizelerin büyük harf olması gerektiğini fark edersiniz - programınızdaki her baskıyı bulup değiştirmelisiniz print data.upper(). Ama varsa def cdata(data): return datave her yerde diyorsa print cdata(data), o zaman sadece değişir def cdata(data): return data.upper()ve tek değişiklik budur.
Corley Brigman

Orada ne demek istediğini anlıyorum. Bu daha mantıklı
Matthew Steeples

2

İşe yaramaz değil, aslında son derece yararlı olabilir, çünkü kodunuzu daha düzgün ve esnek hale getirir.

Örneğin, bir kişi listeniz ve kullanıcının "tümünü" veya yalnızca "erkek" veya "kadın" olanları görmek isteyip istemediğimizi seçmesi için bir açılır listeniz olduğunu varsayalım.

"Tümü" nü özel bir durum olarak işleyebilirsiniz; bu durumda, bu durumu açıkça kontrol etmek için fazladan bir şeye ihtiyacınız olacak veya parametresini döndüren bir filtre işlevine sahip olabilirsiniz (örneğin, her şeyin geçmesine izin verir), "tümü" durumu için kullanılmak üzere atanmış.


4
Bu senaryoya uymuyor. Parametrelerini döndüren bir işlev demek istedim ve hiçbir durumda başka bir şey yapma.
Sempie

@Sempie: Öyle diyor. Eğer bir varsa Filterile sınıf veya arayüzü MaleFilterve FemaleFilteralt sınıfların ve kodunuzu bazı filtre, hiçbir şey yapmaz bir filtre (değişmedi onun parametreyi döndürür) gerektirir sen nasıl idare olduğunu All. İşlev hiçbir şey yapmaz, ancak yerine bir şey konabilir.
Magus

@Magus, ancak senaryonuzda bu işlev ya daha sonra değiştirilecek bir tür yer tutucudur ya da sadece eski işlev eski olduğundan, ancak programın bu geçişe ihtiyacı olduğu için var olur. Her neyse, bir devir teslim değil. İşlev, filtrenin yapabileceği gibi değiştirilmemiş parametreyi başka bir işleve vermez, ancak çağıran işleve döndürür.
Sempie

@Sempie Hayır, ne geçici bir geçiş aracı olarak kullanmak için ne bir yer değiştirici. Bu yararlı bir kodlama (ve matematiksel) kavramı, "kimlik" işlevidir. Ve evet, yine de "başka bir işleve" veya çağıran işleve döndürüp döndürmediği bir aktarımdır. Anahtar, "kimlik" işlevinin çağıran işlev tarafından çağrılan birçok olası işlevden biri olabilmesidir ve kullanılır denilen fonksiyonun bir şey yapması gerekmediğinde özel kasadan kaçınmak için.
Hejazzman
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.