ฟังก์ชั่นส่งกลับเฉพาะพารามิเตอร์ที่ไม่เปลี่ยนแปลงไม่มีประโยชน์หรือไม่


15

ฉันเพิ่งพบฟังก์ชันนี้ในโครงการที่ฉันทำงานอยู่:

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

น่าเศร้าที่ผู้ทำรหัสไม่ทำงานใน บริษัท อีกต่อไป ทำไมหนึ่งจะสร้างฟังก์ชั่นที่ไม่ทำอะไรเลย แต่ส่งกลับพารามิเตอร์ที่เรียกว่าด้วย?

มีการใช้ฟังก์ชันดังกล่าวไม่ได้ระบุตัวอย่างนี้ แต่โดยรวมในกรณีใด ๆ ?

เนื่องจาก

function aFunction(parameter)
    return parameter
end

จบลงแล้ว

aFunction(parameter) == parameter

ทำไมฉันต้องเขียนอะไรบางอย่าง

aFunction(parameter) == whatIWantToCheck

แทน

parameter == whatIWantToCheck

?



13
@gnat วิธีการในโลกที่ซ้ำกันได้อย่างไร
Kilian Foth

13
ฮะ? ฟังก์ชั่นนี้จะส่งกลับพารามิเตอร์ของ - thisผูกมัดเกี่ยวข้องกับการกลับมา
Kilian Foth

11
@gnat คำถามคือทำไมบางคนเคยเขียนฟังก์ชั่นที่ไม่ทำอะไรเลยยกเว้นคืนเอง ใช่คุณสามารถส่งคืนวัตถุหรือค่าบางอย่างเพื่อให้วิธีการผูกมัด แต่ไม่ใช่คำถามของเขา คำถามของเขาคือทำไมบางคนเคยเขียนบางอย่างเช่นint getParam(int param) { //DO NOTHING return param; } จากมุมมองของการโยงวิธีการมันเป็นการโทรซ้ำซ้อนและไม่จำเป็นโดยที่คุณสามารถออกจากฟังก์ชั่นของ OP จากห่วงโซ่วิธีการและมันจะไม่สร้างความแตกต่างเลย
ZeroStatic

4
นี่อาจเป็นเรื่องที่ผิดปกติและไม่ได้ใช้กับ lua แต่มีกรณีการใช้งานที่ถูกต้องสำหรับสิ่งนี้ใน PHP - ในเวอร์ชันเก่าnew Foo()->method();ไม่ใช่ไวยากรณ์ที่ถูกต้องและโครงสร้างเหมือนfunction with($what) { return $what; }; with(new Foo())->method();ถูกใช้เป็นวิธีแก้ปัญหา
DCoder

คำตอบ:


57

คำถามของคุณนั้นเหมือนกับการถามว่าอะไรคือข้อดีของเลขศูนย์ถ้าทุกครั้งที่คุณเพิ่มลงในสิ่งที่คุณได้รับกลับมาเป็นค่าเดิม ฟังก์ชั่นตัวตนเป็นเหมือนศูนย์สำหรับฟังก์ชั่น ชนิดไร้ประโยชน์โดยตัวมันเอง แต่บางครั้งก็มีประโยชน์ในฐานะเป็นส่วนหนึ่งของการแสดงออกโดยใช้ฟังก์ชั่นลำดับสูงกว่าซึ่งคุณสามารถใช้ฟังก์ชั่นเป็นพารามิเตอร์หรือส่งกลับเป็นผล นั่นเป็นสาเหตุที่ภาษาโปรแกรมที่ใช้งานได้ส่วนใหญ่มีidหรือidentityในไลบรารีมาตรฐาน

อีกวิธีหนึ่งคือทำให้เป็นฟังก์ชันเริ่มต้นที่ใช้งานง่าย เช่นเดียวกับที่คุณอาจต้องการตั้งค่าoffset = 0ให้เป็นจำนวนเต็มเริ่มต้นถึงแม้ว่าสิ่งนั้นจะทำให้ออฟเซ็ตไม่ทำอะไรเลยก็ตามมันอาจมีประโยชน์ในการตั้งค่าfilterFunction = identityให้เป็นฟังก์ชั่นเริ่มต้นแม้ว่ามันจะทำให้ตัวกรองไม่ทำอะไรก็ตาม


ฟังก์ชันตัวกรองไม่ควรส่งคืนค่าบูลีนหรือไม่ ในกรณีนี้ฟังก์ชันตัวกรอง "ศูนย์" จะเป็นฟังก์ชันที่คืนค่าจริง
คิริลล์ Rakhman

1
@cypressious ฟังก์ชั่นแผนที่แล้ว
sapi

6
หรือเพื่อติดมันภายใต้แนวคิดการออกแบบ: รูปแบบวัตถุ Null , ฟังก์ชั่นรุ่น
blgt

@cypressious ว่าจะเป็นคำกริยาที่ได้รับการส่งผ่านเป็นอาร์กิวเมนต์เข้าfilterฟังก์ชั่นขั้นสูง ครั้งแรกเพื่อfilterฟังก์ชั่นที่มีชนิด[a] -> [a],
คาร์ล Bielefeldt

ตัวอย่างเช่นใน C # ฉันมักจะใช้.OrderBy(x => x)
CodesInChaos

27

แน่ใจ ลองนึกภาพภายนอก API ที่ช่วยให้คุณสามารถเรียกสิ่งที่มาจากที่ไหนสักแห่งที่คุณต้องการอย่างแน่นอน แต่คุณต้องระบุเกณฑ์การกรองและการจัดรูปแบบการส่งออกสำหรับการค้นหาทุกแม้ว่าคุณต้องการทุกผลและต้องการที่จะได้รับพวกเขาว่าเป็นที่เก็บไว้

จากนั้นคุณจะต้องคิดค้น "ยอมรับทุกสิ่ง" และฟังก์ชั่น "คืนค่าไม่เปลี่ยนแปลง" เล็กน้อยเพื่อรับข้อมูล wtrเป็นเช่นนี้อย่างแน่นอนหลอกฟอร์แมต ถ้าคุณใช้ API นั้นมาก ๆ มันมีประโยชน์มากที่จะให้ฟังก์ชั่นหลอกผู้ช่วยวางอยู่รอบตัวแทนที่จะต้องสร้างฟังก์ชั่นนิรนามเมื่อใดก็ตามที่คุณสอบถามอะไร (คุณอาจลองโทรหามันidentityแทนwtrเพื่อที่จะได้ชัดเจนทันทีว่าไม่ได้ทำอะไรเลย)


ฉันยังไม่เข้าใจความรู้สึกจริงๆ แต่นั่นเป็นสถานการณ์ที่แน่นอน ฉันอาจจะเข้าใจหลังจากผ่านไประยะหนึ่งแล้วฉันคิดว่าการทำงานในโครงการนี้ในขณะที่รักษาคำตอบของคุณไว้ในใจ atm มันดูไร้ประโยชน์สำหรับฉัน ... ถ้าฉันได้รับ rawdata ทำไมฉันถึงต้องการฟังก์ชั่นที่จะให้ฉัน rawdata อีกครั้ง ...
Sempie

3
@Sempie อีกครั้งถ้า API ต้องการฟังก์ชั่นการจัดรูปแบบวิธีเดียวที่จะได้รับข้อความที่ไม่เปลี่ยนแปลงคือถ้าฟังก์ชันไม่ทำอะไรกับข้อความ
Doval

3
กล่าวอีกนัยหนึ่ง: หากคุณมีฟังก์ชั่นที่ต้องผ่านตัวกรอง / รูปแบบอาร์กิวเมนต์และคุณไม่สามารถใช้nullเป็นอาร์กิวเมนต์ได้อย่างแน่นอนคุณใช้ฟังก์ชั่นตัวกรองเปล่าที่กรองด้วย 'ไม่มีอะไร' เพื่อให้โปรแกรมหยุดบ่น
ZeroStatic

3
@Sempie คุณทำงานกับ SQL ใช่ไหม คุณรู้ว่าคุณจะรวมหรือไม่รวมWHEREประโยคได้อย่างไร? นั่นเป็นเรื่องที่เกี่ยวกับวากยสัมพันธ์น้ำตาล โดยพื้นฐานแล้วการหายไปของWHEREประโยคจะเหมือนกับว่าคุณมีWHEREประโยคที่เพิ่งไปข้างหน้าและช่วยให้ทุกอย่าง ความจริงที่ว่านักออกแบบของ SQL ให้คุณไม่ได้ระบุWHEREประโยคแทนที่จะบังคับให้คุณใส่ลงไปแม้ว่ามันจะยอมรับทุกอย่างก็คือน้ำตาล syntactic ที่มากขึ้นหรือน้อยลงและพวกเขาได้ให้ทางเลือกแก่คุณเพื่อความสะดวก ..
Panzercrisis

5
อาจเป็นเรื่องที่น่าสังเกตว่าในหลาย ๆ กรณีจะเร็วและสะอาดกว่าที่จะมีรหัสโดยไม่ต้องเรียกวิธีเสมือนหรือตัวแทนที่อาจมีหรือไม่มีสิ่งที่มีประโยชน์มากกว่าที่จะมีรหัสพิจารณาว่าจำเป็นต้องมีการโทรหรือไม่
supercat

15

นั่นเป็นเพียง polymorphysm ใช่ไหม

จากประสบการณ์ของฉันกับQt tr()และwtr()วิธีการที่ควรจะใช้ (มีในQt ) ในการแปลWidgetข้อความของ

ดังนั้นด้วยการส่งคืนข้อความที่ไม่เปลี่ยนแปลงวิธีการนี้ก็บอกว่า: Widget does no localization (translation of the text) by default. Override this function to enable your own logic.


1
ไม่ได้ตระหนักว่านี่คือสิ่งที่ QT - นี่คือคำตอบที่เห็นได้ชัด
Corley Brigman

8

กรณีที่พบบ่อยมากสำหรับกรณีนี้คือ 'การทำงานที่เพิ่มในภายหลัง' ดังนั้นโปรแกรมเมอร์จึงคิดว่าอาจมีการเปลี่ยนแปลงฟังก์ชั่นนั้นในภายหลัง เนื่องจากคุณเข้าถึงเป็นฟังก์ชั่นและไม่เป็นพารามิเตอร์เองคุณสามารถเปลี่ยนแปลงได้ทั่วโลก ให้บอกว่าคุณมีดัชนีด้วย:

function getIndex(index)
    return index
end

และเมื่อดัชนีของคุณเริ่มต้นที่ 0 ทั้งหมดก็ดี หลังจากนั้นคุณเปลี่ยนส่วนประกอบที่อื่นส่วนประกอบนี้ต้องการให้คุณแปลดัชนีของคุณเพื่อเริ่มต้นที่ 1 คุณจะต้องเพิ่มดัชนีหลายร้อย + 1 ทุกที่ในรหัสของคุณ แต่ด้วยวิธีการเช่นนี้เพียงแค่พูดว่า:

 function getIndex(index)
    return index+1
end

และคุณสบายดี ฟังก์ชั่นเช่นนี้สามารถนำไปสู่การพัฒนาทางวิศวกรรมได้อย่างรวดเร็ว แต่ในบางจุดพวกมันก็สมเหตุสมผล


2
ใช่แม้ว่ามันจะคุ้มค่าที่จะสังเกตว่า Doctstring ของฟังก์ชั่นที่โพสต์โดย OP ไม่แนะนำว่านี่เป็นจุดประสงค์ของฟังก์ชั่นในกรณีของเขา
Mark Amery

6

ฟังก์ชัน Stub เช่นนี้เป็นเรื่องปกติในสถานการณ์การสืบทอดประเภท คลาสพื้นฐานอาจไม่มีประโยชน์อะไร แต่คลาสที่ได้รับอาจทำสิ่งต่าง ๆ ด้วยอินพุต การประกาศฟังก์ชัน stub ในคลาสพื้นฐานอนุญาตให้คลาสที่ได้รับทั้งหมดมีฟังก์ชันของชื่อนั้นและคลาสที่ได้รับจากบุคคลนั้นจะแทนที่มันด้วยสิ่งที่ซับซ้อนและมีประโยชน์มากขึ้น


5

สถานการณ์เพิ่มเติมหนึ่งอย่างนั้นคล้ายคลึงกับการใช้งานในคุณสมบัติของหลามและ C # แต่ในภาษาที่ไม่มีคุณสมบัติ

โดยทั่วไปคุณสามารถประกาศบางสิ่งบางอย่างในฐานะสมาชิกของชั้นเรียน สมมติว่า 'ชื่อ' เป็นสตริง ซึ่งหมายความว่าคุณเข้าถึงแบบนี้:

someobject.name

ต่อมาคุณตัดสินใจว่าชื่อนั้นต้องขึ้นอยู่กับสิ่งที่อยู่ในวัตถุ ดังนั้นมันควรจะเป็นฟังก์ชั่น อ๊ะ! แม้จะไม่มีข้อโต้แย้งนั่นหมายความว่ารหัสทั้งหมดที่เข้าถึงมันจะต้องเปลี่ยนเป็น

someobject.name()

แต่ถ้าคุณมีอินสแตนซ์จำนวนมากในการโทรครั้งนี้โอกาสที่จะเกิดข้อผิดพลาดในระดับนั้นค่อนข้างต่ำ - การเปลี่ยนแปลงนี้จะไม่เกิดขึ้นที่ไหนสักแห่งโปรแกรมจะหยุดทำงานเมื่อคุณไปถึงจุดนั้น ฯลฯ

คุณสมบัติใน C # / Python ช่วยให้คุณสามารถแทนที่ฟังก์ชั่นในสิ่งที่เคยเป็นคุณลักษณะในขณะที่ยังคงให้มันสามารถเข้าถึงได้เช่นคุณลักษณะเช่นไม่มีการเปลี่ยนแปลง คุณไม่จำเป็นต้องวางแผนล่วงหน้า

หากภาษาของคุณไม่มีสิ่งนั้นคุณต้องวางแผนล่วงหน้า แต่คุณยังคงสามารถให้การสนับสนุนได้เหมือนที่คนอื่นเคยทำมาก่อนโดยการทำให้มันเป็นฟังก์ชั่นตั้งแต่ต้นที่ไม่ได้ทำอะไรเลย ในการเริ่มต้นมันจะไม่ทำอะไรที่น่าสนใจและดูเหมือนว่ามันควรจะถูกลบออกและฟังก์ชั่นมากมายของประเภทนี้ไม่เคยเปลี่ยน แต่ต่อมาถ้าคุณรู้ว่าจริง ๆ ทุกครั้งที่คุณโทรหาWidget.wtrคุณจะต้องตัดอักขระพิเศษออกไปมันไม่ใช่เรื่องใหญ่อะไร - มันเป็นฟังก์ชั่นอยู่แล้วคุณแค่เพิ่มมันเข้าไป

TL; DR นี่อาจเป็นการวางแผนโปรแกรมเมอร์ที่ฉลาดล่วงหน้าสำหรับการเปลี่ยนแปลงในอนาคต


3
นั่นจะสมเหตุสมผลถ้าวิธีนี้ขึ้นอยู่กับสิ่งอื่นใด แต่ไม่ได้ มันไม่ใช่คุณสมบัติผู้ทะเยอทะยาน / ผู้ตั้งค่าหรือเขตข้อมูล นี่เป็นวิธีการที่ไม่ได้ทำอะไรเลย วิธีเดียวที่เขาวางแผนสำหรับการเปลี่ยนแปลงในอนาคตคือถ้าตรรกะของวิธีนี้จะต้องเปลี่ยนแปลง
Matthew Steeples

1
ไม่จำเป็นต้อง ... หมายความว่าตอนนี้ฉันไม่ได้ประมวลผลข้อมูลนี้ แต่ต่อมาถ้าฉันต้องการประมวลผลผู้ใช้ทุกคนของข้อมูลนั้นจะได้รับข้อมูลที่ประมวลผลฟรี ตัวอย่างโง่: print dataสมมติว่าคุณพิมพ์สตริงไปที่หน้าจอและคุณมักจะทำ หลังจากนั้นคุณรู้ทุกสายต้องเป็นกรณีบน - print data.upper()คุณจะต้องไปหาพิมพ์ในโปรแกรมและการเปลี่ยนแปลงของคุณทุกคน แต่ถ้าคุณมีdef cdata(data): return dataและทุกที่บอกว่าprint cdata(data)คุณแค่เปลี่ยนไปdef cdata(data): return data.upper()และมันเป็นการเปลี่ยนแปลงเท่านั้น
Corley Brigman

ฉันเห็นสิ่งที่คุณหมายถึงมี นั่นสมเหตุสมผลมากขึ้น
Matthew Steeples

2

มันไม่ไร้ประโยชน์จริง ๆ แล้วมันมีประโยชน์อย่างยิ่งเพราะมันทำให้โค้ดของคุณมีความยืดหยุ่นและสม่ำเสมอยิ่งขึ้น

ตัวอย่างเช่นสมมติว่าคุณมีรายชื่อบุคคลและรายการแบบหล่นลงสำหรับผู้ใช้เพื่อเลือกว่าเราต้องการเห็น "ทั้งหมด" หรือเฉพาะรายการที่เป็น "ชาย" หรือ "หญิง"

คุณสามารถจัดการ "all" เป็นกรณีพิเศษซึ่งในกรณีนี้คุณจะต้องเพิ่มถ้าและเพื่อตรวจสอบกรณีนี้อย่างชัดเจนหรือคุณสามารถมีฟังก์ชั่นตัวกรองที่เพิ่งส่งคืนพารามิเตอร์ของมัน (เช่นอนุญาตให้ทุกอย่างผ่าน) มอบหมายให้ใช้สำหรับกรณี "ทั้งหมด"


4
ที่ไม่เหมาะสมกับสถานการณ์ ฉันหมายถึงฟังก์ชั่นที่คืนค่าพารามิเตอร์ของเขาและไม่ว่าในกรณีใด
Sempie

@Sempie: นั่นคือสิ่งที่เขาพูด หากคุณมีFilterชั้นเรียนหรืออินเตอร์เฟซที่มีMaleFilterและFemaleFiltersubclasses และรหัสของคุณต้องใช้ตัวกรองบางตัวกรองที่ไม่ทำอะไรเลย (ที่ส่งกลับพารามิเตอร์ไม่เปลี่ยนแปลง) Allเป็นวิธีที่คุณจัดการ ฟังก์ชั่นไม่เคยทำอะไรเลย แต่สามารถทดแทนสิ่งที่ทำ
Magus

@Magus แต่ในสถานการณ์ของคุณฟังก์ชั่นเป็นตัวยึดตำแหน่งที่จะถูกแทนที่ในภายหลังหรือเพียงแค่มีอยู่เพราะฟังก์ชั่นเก่าล้าสมัย แต่โปรแกรมต้องการ passthrough นี้ อย่างไรก็ตามมันไม่ใช่การส่งมอบ ฟังก์ชั่นไม่ได้ให้พารามิเตอร์ที่ไม่เปลี่ยนแปลงกับฟังก์ชั่นอื่นตามที่ฟิลเตอร์อาจทำ แต่จะส่งกลับไปยังฟังก์ชันการเรียก
Sempie

@Sempie ไม่มันไม่ใช่ตัวยึดตำแหน่งไม่ใช่ใช้เป็น passthrough ชั่วคราว มันเป็นความคิดที่มีประโยชน์ในการเข้ารหัส (และคณิตศาสตร์) ฟังก์ชัน "เอกลักษณ์" และใช่มันยังคงส่งมอบไม่ว่าจะส่งกลับไปที่ "ฟังก์ชั่นอื่น" หรือฟังก์ชั่นการโทรที่สำคัญคือฟังก์ชั่น "ตัวตน" สามารถเป็นหนึ่งในฟังก์ชั่นที่เป็นไปได้หลายอย่างที่เรียกโดยฟังก์ชั่นการโทรและใช้ เพื่อหลีกเลี่ยงถ้าและเคสพิเศษเมื่อฟังก์ชันที่เรียกใช้ไม่จำเป็นต้องทำอะไร
Hejazzman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.