ฉันใหม่มากสำหรับ Clojure พวกคุณช่วยอธิบายสถานการณ์ในโลกแห่งความจริงให้ฉันได้ไหม ฉันหมายถึงที่ที่จะใช้ Ref, Var, Agent, Atom ฉันอ่านหนังสือ แต่ยังไม่เข้าใจตัวอย่างในโลกแห่งความเป็นจริง
ฉันใหม่มากสำหรับ Clojure พวกคุณช่วยอธิบายสถานการณ์ในโลกแห่งความจริงให้ฉันได้ไหม ฉันหมายถึงที่ที่จะใช้ Ref, Var, Agent, Atom ฉันอ่านหนังสือ แต่ยังไม่เข้าใจตัวอย่างในโลกแห่งความเป็นจริง
คำตอบ:
ฉันขอแนะนำ "The Joy of Clojure" หรือ "Programming Clojure" สำหรับคำตอบที่แท้จริงสำหรับคำถามนี้ฉันสามารถสร้างแรงจูงใจสั้น ๆ ของแต่ละข้อได้ดังนี้
เริ่มต้นด้วยการดูวิดีโอนี้ในความคิดของรหัสประจำตัวและ / หรือการศึกษาที่นี่
การเข้าถึงที่ประสานงานจะใช้เมื่อข้อมูลประจำตัวสองตัวจำเป็นต้องเปลี่ยนแปลงร่วมกันตัวอย่างคลาสสิกคือการย้ายเงินจากบัญชีธนาคารหนึ่งไปยังอีกบัญชีหนึ่งจำเป็นต้องย้ายทั้งหมดหรือไม่ย้ายเลย
การเข้าถึงแบบไม่ประสานกันจะใช้เมื่อต้องอัปเดต Identity เพียงตัวเดียวซึ่งเป็นกรณีที่พบบ่อยมาก
การเข้าถึงแบบซิงโครนัสถูกใช้เมื่อคาดว่าการโทรจะรอจนกว่าข้อมูลประจำตัวทั้งหมดจะตกลงก่อนดำเนินการต่อ
การเข้าถึงแบบอะซิงโครนัสคือ "จุดไฟและลืม" และปล่อยให้ข้อมูลประจำตัวไปถึงสถานะใหม่ในเวลาของตัวเอง
ensure
ฟังก์ชัน: clojure.github.io/clojure/clojure.core-api.html#clojure.core/…เพื่อทำให้สิ่งนี้ชัดเจนและมีประสิทธิภาพมากขึ้น
Refs ใช้สำหรับสถานะที่ต้องซิงโครไนซ์ระหว่างเธรด หากคุณต้องการติดตามสิ่งต่างๆมากมายและบางครั้งคุณจะต้องดำเนินการที่เขียนถึงหลายสิ่งพร้อมกันให้ใช้การอ้างอิง ทุกครั้งที่คุณมีสถานะที่แตกต่างกันการใช้ refs ไม่ใช่ความคิดที่ดี
อะตอมเป็นสถานะอิสระที่ต้องซิงโครไนซ์ระหว่างเธรด หากคุณไม่จำเป็นต้องเปลี่ยนสถานะของอะตอมและสิ่งอื่นใดในเวลาเดียวกันการใช้อะตอมนั้นปลอดภัย (โดยเฉพาะอย่างยิ่งหากมีสถานะเพียงชิ้นเดียวในโปรแกรมทั้งหมดคุณสามารถใส่ไว้ในอะตอมได้) . เป็นตัวอย่างที่ไม่สำคัญหากคุณพยายามแคชค่าที่ส่งคืนของฟังก์ชัน (เช่นบันทึก) การใช้อะตอมอาจปลอดภัย - สถานะจะมองไม่เห็นทุกสิ่งที่อยู่นอกฟังก์ชันดังนั้นคุณไม่จำเป็นต้องกังวล เกี่ยวกับการเปลี่ยนแปลงสถานะภายในฟังก์ชั่นที่ทำให้เกิดความสับสน
จุดหลักของตัวแทนคือพวกเขาทำงานในเธรดอื่น คุณสามารถรับค่าของเอเจนต์และบอกให้ใช้ฟังก์ชันกับค่าของมันได้ แต่คุณไม่รู้ว่าฟังก์ชันจะทำงานเมื่อใดหรือฟังก์ชันจะถูกนำไปใช้กับค่าใด
Vars มีไว้สำหรับเมื่อคุณต้องการจัดเก็บบางอย่างแบบต่อเธรด หากคุณมีโปรแกรมมัลติเธรดและแต่ละเธรดต้องการสถานะส่วนตัวของตัวเองให้ใส่สถานะนั้นในตัวแปร
เท่าที่ดูในโลกแห่งความเป็นจริงถ้าคุณให้ตัวอย่างสิ่งที่คุณพยายามทำเราสามารถบอกคุณได้ว่าจะใช้อะไร
เมื่อฉันอ่านเกี่ยวกับประเภทเหล่านี้เป็นครั้งแรกฉันก็พยายามที่จะเข้าใจว่าฉันสามารถหรือควรใช้แต่ละประเภทได้ที่ไหนดังนั้นนี่คือคำตอบภาษาอังกฤษธรรมดาของฉัน:
ใช้ var เมื่อข้อมูลไม่เปลี่ยนแปลง เรื่องนี้เกิดขึ้นเมื่อใดก็ตามที่คุณใช้def
หรือฟังก์ชั่นมากที่สุดที่เริ่มต้นด้วยเช่นdef
defn
ใช้อะตอมเมื่อคุณมีรายการเดียวที่เปลี่ยนแปลง ตัวอย่างอาจเป็นตัวนับหรือเวกเตอร์ที่คุณต้องการเพิ่มรายการ
ใช้การอ้างอิงเมื่อคุณมีสองสิ่งขึ้นไปที่ต้องเปลี่ยนแปลงในเวลาเดียวกัน คิดว่า "ธุรกรรมฐานข้อมูล" ถ้าคุณคุ้นเคย ตัวอย่างที่ยอมรับได้คือการโอนเงินจากบัญชีหนึ่งไปยังอีกบัญชีหนึ่ง แต่ละบัญชีสามารถจัดเก็บใน ref เพื่อให้การเปลี่ยนแปลงปรากฏเป็นปรมาณู
ใช้ตัวแทนเมื่อคุณต้องการเปลี่ยนแปลงบางอย่าง แต่คุณไม่สนใจว่าเมื่อไร นี่อาจเป็นการคำนวณที่ยาวนานหรือเขียนบางอย่างลงในไฟล์หรือซ็อกเก็ต โปรดทราบว่าคุณควรใช้send-off
หลัง
หมายเหตุ: ฉันขอขอบคุณที่แต่ละสิ่งมีมากกว่านี้ แต่หวังว่านี่จะเป็นจุดเริ่มต้นให้คุณ
ฉันเขียนบทความพร้อมสรุปความแตกต่างและช่วยเลือกว่าจะใช้เมื่อใด
Share state - เมื่อใช้ vars, atoms, agent และ refs?
ฉันหวังว่ามันจะช่วยให้ผู้ที่กำลังมองหาคำตอบในหัวข้อนั้น
ทางลัดบางส่วนจากบทความหลังคำแนะนำ @tunaci:
Vars
Vars เป็นแบบสากลสำหรับทุกเธรด
อย่าเปลี่ยน vars หลังจากสร้าง เป็นไปได้ในทางเทคนิค แต่เป็นความคิดที่ไม่ดีด้วยเหตุผลหลายประการ
อะตอม
แบ่งปันการเข้าถึงสถานะที่ไม่แน่นอนสำหรับทุกเธรด การเปลี่ยนแปลงเกิดขึ้นพร้อมกัน ลองอีกครั้งเมื่อเธรดอื่นเปลี่ยนสถานะระหว่างการรัน
อย่าใช้ฟังก์ชันและฟังก์ชันที่ไม่ได้ใช้งานที่มีการดำเนินการเป็นเวลานาน
ตัวแทน
แบ่งปันการเข้าถึงสถานะที่ไม่แน่นอนสำหรับทุกเธรด การเปลี่ยนแปลงเกิดขึ้นแบบอะซิงโครนัส
อ้างอิง
Refs ทำงานคล้ายกับธุรกรรมฐานข้อมูล การเขียนและการอ่านได้รับการปกป้องใน dosync คุณสามารถดำเนินการกับผู้อ้างอิงจำนวนมากที่ปลอดภัยในการทำธุรกรรม
โปรดดูภาพบนเว็บไซต์เนื่องจากการอัปเดตบางอย่างสามารถทำได้ตลอดเวลา
มันซับซ้อนและเป็นหัวข้อที่ยาวในการให้คำตอบโดยไม่ต้องคัดลอกและบทความที่ผ่านมาดังนั้นโปรดยกโทษให้ฉันด้วยฉันเปลี่ยนเส้นทางคุณไปที่เว็บไซต์ :)
อะตอมผู้อ้างอิงและตัวแทน - การส่องสว่างบางส่วนที่นี่ http://blog.jayfields.com/2011/04/clojure-state-management.html
state-a
แต่อ้างถึงstate-b
ในการดำเนินการดังกล่าวฉันยังต้องการความref
ถูกต้องหรือไม่? ดังนั้นจึงไม่ได้เปลี่ยนหลายสิ่ง แต่หมายถึงหลายสิ่งในขณะที่เปลี่ยนสิ่งเหล่านี้หรือไม่?