คำที่ใช้อธิบายฟังก์ชั่น / วิธีที่แก้ไขวัตถุที่ถูกเรียกนั้นคืออะไร?


12

ขออภัยสำหรับคำถามทั่วไป ฉันค้นหาทั่วและพบกระทู้จำนวนมากที่คล้ายกันนี้ แต่ไม่ใช่หนึ่งที่ตอบคำถามเฉพาะของฉัน - บางทีอาจเป็นเพราะคำที่ฉันค้นหาไม่มีอยู่

เพื่อนคนหนึ่งของฉันคือการเรียนรู้การเขียนโปรแกรมจาวาสคริปต์โดยเฉพาะและเขาถามฉันว่าทำไมมันถึงไม่ทำงาน:

var a = "Hello World";
a.replace("Hello", "Goodbye");

console.log(a)  // Logs "Hello World"

เหตุผลเป็นเพราะreplaceไม่ได้แก้ไขaเนื่องจากสตริงไม่เปลี่ยนรูปใน JavaSript เพราะมันส่งคืนสตริงคุณต้องทำอะไรบางอย่างเช่น ...

var a = "Hello World";
a = a.replace("Hello", "Goodbye");

console.log(a);  // Logs "Goodbye World"

อย่างไรก็ตามทางเลือกคือฟังก์ชั่นเช่นจาวาสคริปต์reverse()เพราะมันจะทำการแก้ไขสิ่งที่เรียกว่า ตัวอย่างเช่น:

var fruits = ["Apples", "Oranges", "Bananas"];
fruits.reverse();

console.log(fruits)  // ["Bananas", "Oranges", "Apples"]

เมื่อเพื่อนของฉันถามฉันว่าทำไมเขาถึงreplaceไม่ทำงานฉันก็รู้ตัวว่ากำลังพูดถึงคำที่ฉันไม่รู้ (เท่าที่ฉันรู้) ...

"คุณต้องตั้งค่าสตริงเป็น" string dot replace "เนื่องจากฟังก์ชันแทนที่คือ ________"

คุณไม่จำเป็นต้องตั้งค่าอาร์เรย์ให้เท่ากับ "array dot reverse" เพราะ reverse เป็น ________

ฉันคุ้นเคยกับฟังก์ชั่นต้นแบบแม้ว่าฉันไม่เชื่อว่าเป็นคำที่ฉันกำลังมองหา ใครสามารถช่วยฉันเติมลงในช่องว่างเหล่านี้ได้ไหม


6
บางทีคำว่า "mutator"? You don't need to set an array equal to "array dot reverse", because reverse is a mutator functionเช่นเดียวกับใน: ฉันคิดว่าฉันได้ยินคำศัพท์ที่อ้างถึงฟังก์ชั่นที่ "กลายพันธุ์" อินสแตนซ์ที่เรียกพวกเขา แต่คุณควรตรวจสอบอีกครั้งว่าที่อื่น
FrustratedWithFormsDesigner

ขอบคุณมัน! ฉันเพิ่งได้อ่านวิธีการเปลี่ยนแปลงและฉันคิดว่ามันเหมาะกับการสนทนานี้ค่อนข้างดี แน่นอนในขอบเขตของสิ่งที่ฉันกำลังมองหา
Santi

ผมสับสนในชื่อคุณถามเกี่ยวกับฟังก์ชั่นที่ปรับเปลี่ยนวัตถุที่เรียกมันว่า แต่ในตัวอย่างของคุณคุณแสดงให้เห็นวิธีการที่ปรับเปลี่ยนวัตถุที่พวกเขาเรียกว่าบนคือตรงข้ามแน่นอนของชื่อ สองอันไหนกัน?
Jörg W Mittag

แน่นอนว่าคนที่อธิบายในรายละเอียด 30 บรรทัด ฉันจะแก้ไขชื่อให้ถูกต้องขอบคุณสำหรับ heads-up!
Santi

คำตอบ:


12

คู่ของแนวคิดที่คุณกำลังค้นหาคือพารามิเตอร์ที่เปลี่ยนแปลงไม่ได้ / ไม่เปลี่ยนรูปและผลลัพธ์แบบแทนที่

ในตัวอย่างของคุณ:

คุณต้องตั้งค่าสตริงเป็น "string dot replace" เนื่องจากฟังก์ชั่นแทนที่ทำงานบนสตริงซึ่งในไพ ธ อนนั้นไม่เปลี่ยนรูปดังนั้นฟังก์ชันแทนที่จะส่งคืนสตริงใหม่

สำหรับโปรแกรมเมอร์ C / C ++ สิ่งนี้จะคุ้นเคยมากกว่าในเรื่องพารามิเตอร์ "ส่งผ่านตามค่า" แทนที่จะเป็น "ส่งผ่านโดยการอ้างอิง" ซึ่งทำให้พวกมันไม่เปลี่ยนรูปและส่งคืนผลลัพธ์

คุณไม่จำเป็นต้องตั้งค่าอาร์เรย์เท่ากับ "array dot reverse" เนื่องจาก reverse ทำงานบนอาร์เรย์ซึ่งไม่แน่นอนดังนั้นจึงสามารถทำการเปลี่ยนแปลงในสถานที่ก่อนที่จะกลับมา

ในภาษาเช่น C / C ++ นี้เป็นที่รู้จักกันเป็นพารามิเตอร์ "ผ่านอ้างอิง" คือการส่งผ่านที่อยู่ซึ่งหากไม่มีการแก้ไขโดยconst,ช่วยให้การทำงานเพื่อการเปลี่ยนแปลงกลายพันธุ์เนื้อหาของอยู่ที่การแก้ไขผลในสถานที่ก่อนที่จะกลับ

แน่นอนมันเป็นเรื่องปกติที่จะมีฟังก์ชั่นที่ผลตอบแทนโดยทั้งสองกลไกเช่นint SomeFn(int p1, int p2, int *ErrCode)สามารถที่อาจเกิดErrCodeผลกลับทั้งในค่าตอบแทนและโดยการปรับเปลี่ยนเนื้อหาของ

วิธีที่ 3

เพื่อความสมบูรณ์กลไกที่ 3 สำหรับการส่งคืนผลลัพธ์คือผลข้างเคียงหรือทั่วโลกเช่นการแก้ไขขอบเขตไฟล์ค่าโปรแกรมกว้างค่าที่แชร์หรือสภาพแวดล้อม โดยทั่วไปถือว่าเป็นข่าวร้ายเนื่องจากคุณจะสามารถทราบได้ว่ามีการเปลี่ยนแปลงอะไรบ้างโดยการอ่านโค้ดอย่างระมัดระวัง ในภาษาเช่น C / C ++ นี่คือทั้งหมดที่ง่ายเกินไปที่จะทำโดยมีตัวแปรขอบเขตด้านนอกที่มีชื่อที่กำหนดอาจเป็นไปได้ในโมดูลอื่นและไม่มีการปิดบังตัวแปรขอบเขตท้องถิ่นของชื่อเดียวกัน ใน Python ในขณะที่คุณสามารถอ่านค่าของค่าในขอบเขตด้านนอกยกเว้นว่าค่าขอบเขตด้านนอกจะถูกตั้งค่าอย่างชัดเจนตามที่พร้อมจะแก้ไขด้วยglobal คำหลักพยายามแก้ไขตัวแปรขอบเขตด้านนอกสร้างท้องถิ่นที่มีชื่อเดียวกันโดยอัตโนมัติ


อาฉันคุ้นเคยกับคำศัพท์เหล่านี้ถึงแม้ว่าฉันจะไม่แน่ใจว่ามีคำจริง ๆ ที่อธิบายการทำงานของตัวเองหรือไม่ ในขณะที่(The reverse function is a _______ function.) ถูกกล่าวว่านี่เป็นคำตอบที่เกือบเหมือนกันกับที่ฉันลงเอยให้เพื่อนของฉันดังนั้นฉันขอขอบคุณการยืนยันของคุณ - แม้ว่าฉันยังคงสงสัยว่ามีคำเฉพาะ ฉันจะปล่อยให้คำถามเปิดอยู่สักพัก แต่จะยอมรับอย่างแน่นอนเพราะคำตอบในกรณีที่คำเหล่านี้ไม่มีอยู่จริง
Santi

2
ในบางภาษาเช่น python คุณสามารถมีคลาสที่ปรับเปลี่ยนตัวเองได้ในขณะที่ในบางบริบทนี้ "การปะของลิง" ถือว่าเป็นสิ่งที่ดีในหลาย ๆ อย่างซึ่งถือว่าเป็น "การแก้ไขด้วยตนเอง" และเป็นสิ่งต้องห้าม นอกจากนี้คุณยังสามารถมี "รหัสวิวัฒนาการ" โดยที่ส่วนรหัสจะถูกสุ่ม "กลายพันธุ์" และ / หรือรวมกันจากนั้นจะถูกทดสอบและเลือกสำหรับประสิทธิภาพ "ดีที่สุด" ในบางลักษณะ
Steve Barnes

-1 ไม่ว่าสตริงนั้นจะไม่แน่นอนหรือไม่เปลี่ยนรูปนั้นไม่เกี่ยวข้องกับฟังก์ชั่นที่ใช้งานอยู่ ฟังก์ชั่นไม่สามารถเปลี่ยนแปลงได้หรือไม่เปลี่ยนรูปแบบและไม่ได้ "ส่งคืนหรือแทนที่" ฟังก์ชั่นสามารถแก้ไขข้อโต้แย้งของพวกเขาและยังคงกลับมา
Miles Rout

@MilesRout เพิ่มว่าฟังก์ชั่นที่ปรับเปลี่ยนในสถานที่ยังคงกลับมาและตัวอย่าง C / C ++ บางอย่างเพื่อความชัดเจนบวกผลลัพธ์โดยผลข้างเคียงเพื่อความสมบูรณ์
Steve Barnes

4

วิธีที่ฉันชอบในการแสดงคือ:

  • อาร์เรย์reverseวิธีการที่กรรมวิธี มันเป็นMutator เป็นกรณีพิเศษร่วมกันเป็นหมา

  • สตริงreplaceเป็นวิธีการที่ไม่ใช่ mutating มันไม่ Mutator ถ้ามันไม่ได้ปรับเปลี่ยนอะไรก็ของผลข้างเคียงฟรี เป็นกรณีพิเศษที่พบบ่อยคือทะเยอทะยาน

  • เนื่องจาก JavaScript สตริงไม่เปลี่ยนรูปวิธีการสตริงจึงไม่สามารถกลายพันธุ์

    "Hello World" .replace ("Hello", "Goodbye");

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

  • เนื่องจากอาร์เรย์ของ JavaScript สามารถเปลี่ยนแปลงได้วิธี Array จึงสามารถกลายพันธุ์ได้ JavaScript มีแนวโน้มที่จะใช้อาร์เรย์เป็นถังขยะในพื้นที่จัดเก็บแก้ไขและคัดลอกได้ง่าย

2

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

ในกรณีของคุณคุณจะพูดว่า:

คุณจะต้องตั้งสตริงสตริง "จุดเปลี่ยน" เพราะแทนที่ฟังก์ชันไม่ทำลาย

คุณไม่จำเป็นต้องตั้งค่าอาร์เรย์เท่ากับ "อาร์เรย์จุดกลับ" เพราะย้อนกลับคือการทำลายล้าง


1

บางทีคำที่คุณกำลังมองหาอาจจะบริสุทธิ์ ?

replace()is (หรือดูเหมือนจะเป็น) บริสุทธิ์เพราะดูเหมือนว่ามันมีผลข้างเคียงใด ๆ (เช่นการปรับเปลี่ยนสตริง) ในขณะที่reverse()ไม่บริสุทธิ์เพราะมันจะเปลี่ยนสถานะของอาร์เรย์


มันเป็นแนวคิดที่เกี่ยวข้อง แต่ก็หมายถึงคุณสมบัติอื่น ๆ (เช่นไม่เข้าถึงสถานะโลกและให้ผลผลิตเดียวกันสำหรับอินพุตเดียวกันเสมอ)
Jacob Raihle

1

สิ่งเหล่านี้มักจะถูกแยกออกเป็นฟังก์ชันและเมธอด (โดยที่เมธอดเป็นส่วนย่อยของฟังก์ชัน) ฟังก์ชั่นเป็นส่วนหนึ่งของรหัสที่สามารถเรียกว่าในการแยกในขณะที่วิธีการมีแนวคิดของ 'บริบท' ปัจจุบันที่มันทำงาน การกระทำของวิธีการเปลี่ยนสถานะของบริบท

ในการเขียนโปรแกรมเชิงวัตถุบริบทเป็นอินสแตนซ์ที่ทำงานอยู่


0

ฉันไม่รู้ว่ามีคำตอบอย่างเป็นทางการ แต่คุณอาจชอบสองคนนี้

ขั้นตอน

เพียงเพราะมันดูเหมือนคำตอบที่ดีสำหรับคำถามนี้ซึ่งดูเหมือนคำถามของคุณ BTW - คุณควรตรวจสอบ

การดำเนินการ unary ในสถานที่

ตรวจสอบหน้านี้: java.util.function มันมีการเรียงลำดับของชื่อทำขึ้นสำหรับผู้ได้รับมอบหมาย (ลายเซ็นอินพุต / เอาต์พุต) ต้นแบบต่างๆเช่นผู้ร่วมประชุมซึ่งจะมีข้อโต้แย้งและผลตอบแทนที่ไม่มีอะไรที่เรียกว่าผู้บริโภค

ตอนนี้ในฐานะนักเรียนที่ฉลาดของ OOP คุณควรทราบว่าวิธีการหนึ่งเป็นเพียงฟังก์ชันที่ใช้พารามิเตอร์ที่ซ่อนอยู่ ( this) เนื่องจากเป็นข้อมูลอ้างอิงจึงทำหน้าที่เป็นทั้งอินพุตและพารามิเตอร์เอาต์พุต

ตามที่เหล่านี้พวก Java (และพวกเขาดูเหมือนสวยสมาร์ท) ตัวแทนที่รับอินพุตเดียวและส่งกลับค่าของชนิดเดียวกันที่เรียกว่าผู้ประกอบการเอก

ในกรณีนี้array::Reverse()อาร์เรย์ไม่เปลี่ยนรูปและอาจใช้พื้นที่มากดังนั้นจึงมีประสิทธิภาพและสะดวกในการดำเนินการแทน ดังนั้นจึงReverse()เป็นในสถานประกอบการเอก

แต่การที่ฉันเป็น "ผู้ประกอบการ" เป็นสัญลักษณ์พิเศษ (เช่นผู้ประกอบการนอกจากนี้ยังเป็นที่รู้จัก+) modหรือคำหลักทางคณิตศาสตร์เช่น ดังนั้นผมจึงชอบที่จะเรียกมันว่า operat ไอออนผลผลิตในสถานที่การดำเนินการเอกภาค


คุณกำลังมั่วแนวคิด Reverse()ไม่ได้เป็นผู้ประกอบการจำเป็นที่จะต้องดำเนินการเอกไม่กลับค่าของประเภทเดียวกัน (เช่น!, delete, typeof) และผู้ประกอบการไม่ได้รับมอบหมาย แต่ "ในสถานที่" เป็นคำที่ดีสำหรับวิธีการที่ปรับเปลี่ยนอินสแตนซ์ของมัน [ฉันไม่ลงคะแนน แต่ดูเหมือนว่ามีคนโหวตคำตอบทั้งหมดแม้ว่าพวกเขาจะมีประโยชน์ทั้งหมด]
Jerry101

ไม่แน่ใจว่าคุณกำลังติดตาม ต้นแบบใด ๆ สามารถแสดงโดยผู้รับมอบสิทธิ์ "โอเปอเรเตอร์" ไม่ทำงานสำหรับฉัน (ตามที่ระบุไว้) ดังนั้นฉันจึงพูดว่า "การดำเนินการ" และใช่Reverse()เป็นการดำเนินการที่เป็นเอกเทศ แต่โดยรวมแล้วฉันเห็นด้วยว่านี่เป็นสิ่งที่แปลกเล็กน้อย แต่ฉันใช้คำต่อคำจากเอกสารที่เชื่อมโยงซึ่งดูเหมือนว่าจะได้รับการประพันธ์โดยคนฉลาดบางคน อย่างน้อยก็ยังดีกว่าไม่มีอะไร
John Wu

อ้อเข้าใจแล้ว! โปรดทราบว่าการติดตั้งแลมบ์ดาเข้าไปใน Java พวกมันสร้างขึ้นจากแนวคิดของส่วนต่อประสานการทำงาน (ส่วนต่อประสาน Java ด้วยวิธีการเพียง 1 วิธี) ดังนั้นเราจึงสามารถผ่านวัตถุ Java ธรรมดาเพื่อใช้เป็น "ฟังก์ชั่น" (Brian Goetz มีการพูดคุยทางเทคนิคเกี่ยวกับการเพิ่ม lambdas หลายครั้งที่เขาพูดว่า "วิธีการที่ชัดเจนจะถูกดูด") เมื่อสร้างส่วนต่อประสานการทำงานสำหรับวัตถุการประมวลผลสตรีม มันช่างสับสน! พวกเขาจะต้องไม่มีชื่อที่ดี ฉันไม่คิดว่ามันเป็นแหล่งที่มาของคำศัพท์ที่ดีสำหรับวิธีการของ OOP ที่ทำ / ไม่แก้ไขวัตถุผู้รับ
Jerry101
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.