Getters และ Setters ในภาษาที่ใช้งานได้


9

หนึ่งในหลักของการเขียนโปรแกรมฟังก์ชั่นคือการใช้ฟังก์ชั่นบริสุทธิ์ ฟังก์ชั่น Pure เป็นฟังก์ชันที่ปราศจากผลข้างเคียงและโปร่งใสอ้างอิง

Gettersไม่โปร่งใสในการอ้างอิง - หาก Setter ถูกเรียกระหว่างการเรียกไปยัง Getter ค่าส่งคืนของ Getter จะเปลี่ยนแม้ว่าพารามิเตอร์จะไม่มี (โดยทั่วไปจะไม่มีพารามิเตอร์)

Settersสร้างผลข้างเคียง - การเรียก Setter โดยทั่วไปจะจัดการกับค่าที่ไม่ใช่ค่าส่งคืน (อันที่จริงแล้วโดยทั่วไปแล้ว Setter จะไม่ส่งคืนค่าใด ๆ )

ฉันรู้ว่าในสกาล่าเราแค่ยอมรับความจริงที่ว่าเรากำลังผสานสองกระบวนทัศน์ (เชิงหน้าที่และเชิงวัตถุ) และใช้ getters / setters ตามที่เราต้องการในภาษาเช่น Java

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

วิธีการแก้ปัญหาจะส่งกลับสำเนาของวัตถุที่ setter ถูกเรียกเมื่อเป็นค่าส่งคืนของ setter และสำเนานี้มีการเปลี่ยนแปลงค่าทรัพย์สิน?


8
Getters และ setters มีวัตถุเป็นพารามิเตอร์ - แม้ว่าโดยทั่วไปจะเป็นนัย - ดังนั้น getters จึงมีความโปร่งใสในการอ้างอิง

@delnan เฉพาะเมื่อแอตทริบิวต์ที่อ่านอยู่นั้นไม่เปลี่ยนรูป
dan_waterworth

3
@dan_waterworth: เฉพาะเมื่อเราอ่าน "เดียวกัน" ใน "โปร่งใสอ้างอิง" เป็นเอกลักษณ์ของวัตถุ หากข้อเท็จจริงคุณลักษณะที่แตกต่างกันทำให้การโทรด้วยอาร์กิวเมนต์ที่แตกต่างกัน (ซึ่งสอดคล้องกับคำจำกัดความส่วนใหญ่ของความเท่าเทียมกัน) นี่คือการละเว้นเธรดอื่นที่เรียกตัวเซ็ตเตอร์และจบระหว่างการเรียกไปยังตัวทะแลและตัวจบทะลุ แต่ในกรณีนี้คุณมีปัญหาร้ายแรงมากขึ้นอยู่ดี

คำตอบ:


7

เผง ดูวิธีคลาสเคสcopyหรือแนวคิดทั่วไปของเลนส์

โดยเฉพาะอย่างยิ่งหากรัฐต้องการเปลี่ยนแปลงคุณจะต้องใช้ monad รัฐ การเปลี่ยนแปลงสถานะ monad นั้นสามารถทำได้ผ่านเลนส์ซึ่งทำให้สามารถดึงข้อมูลจาก "สถานะ" และเปลี่ยนได้ง่าย

ดูคำถามนี้เกี่ยวกับปัญหาทั่วไปที่มาจากโครงสร้างที่ลึกเช่น "สถานะ" และการเปลี่ยนแปลง คำตอบมีลิงค์ที่ดีเกี่ยวกับเลนส์และซิปถ้าคุณต้องการเจาะลึกลงไป


คำถามแดเนียล: มีเหตุผลใดที่ลอก () เชื่อมโยงกับชั้นเรียนกรณีหรือไม่ สิ่งนี้ไม่ได้เฉพาะเจาะจงกับความต้องการ (คำผิด แต่ไม่สามารถคิดได้อีก) ของคลาสเคสโดยเฉพาะดูเหมือนว่า (สำหรับฉัน) คุณสมบัติอื่น ๆ ที่เหมาะสำหรับทุกชั้นเรียน จะทำอย่างไรถ้าฉันต้องการ copy () ในคลาสที่ไม่ใช่กรณีของฉัน มีลักษณะที่ฉันสามารถใช้เพื่อรับฟังก์ชั่นนั้นหรือไม่?
ThaDon

1
คลาสเคส @ThaDon ควรถูกกำหนดโดยพารามิเตอร์ Constructor ของพวกเขา - ความเท่าเทียมกันของรหัสแฮชและตัวแยกข้อมูลจะขึ้นอยู่กับสมมติฐานนี้และดังนั้นจึงเป็นวิธีการคัดลอก ในคลาสที่ไม่ใช่กรณีนั้นจะมีใครเดาว่าพารามิเตอร์คอนสตรัคเป็นสิ่งที่จำเป็นในการคัดลอกชั้นเรียน อย่างไรก็ตามคุณสามารถเขียนวิธีการคัดลอกของคุณเองได้อย่างง่ายดาย
Daniel C. Sobral

11

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


1
"วัตถุ (มัก) ไม่เปลี่ยนรูป" เมื่อพวกเขาไม่?
sara

-1

"Getters และ setters มีวัตถุเป็นพารามิเตอร์ - แม้ว่าโดยทั่วไปจะเป็นนัย - ดังนั้น getters จะอ้างอิงได้อย่างโปร่งใส - delnan"

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


แต่ถ้าวัตถุถูกเปลี่ยนโดย setter อินพุตไปยัง getter (เช่นอาร์กิวเมนต์ตัวเองโดยนัย) HAS เปลี่ยนไป
สตีเฟ่นซี. เหล็ก

1
ค่าการอ้างอิงวัตถุ / ตัวชี้ไม่เปลี่ยนแปลงเว้นแต่ว่าวัตถุนั้นถูกย้ายไปบนฮีป
Casey Hawthorne

5
ใช่ แต่มีเหตุผลอินพุตโดยนัยคือวัตถุเองไม่ใช่ค่าของตัวชี้
สตีเฟ่นซี. เหล็ก

"ถ้า setter มีการเปลี่ยนแปลงคุณสมบัติของวัตถุคุณจะไม่ได้ผลลัพธ์ที่เหมือนกัน": ในแง่ของการใช้งานคุณได้ทำลายวัตถุแรกและสร้างวัตถุใหม่ เพื่อเหตุผลด้านประสิทธิภาพ (หลีกเลี่ยงการคัดลอกและอัปเดตการอ้างอิงจากวัตถุเก่าไปยังวัตถุใหม่) คุณกำลังจัดเก็บวัตถุใหม่ในพื้นที่หน่วยความจำเดียวกันที่มีวัตถุเก่า
จอร์โจ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.