Câu trả lời:
Tôi thực sự khuyên bạn nên sử dụng "Niềm vui của Clojure" hoặc "Lập trình Clojure" để có câu trả lời thực sự cho câu hỏi này, tôi có thể tái tạo một đoạn ngắn về động lực cho mỗi:
bắt đầu bằng cách xem video này về khái niệm Nhận dạng và / hoặc nghiên cứu ở đây .
Quyền truy cập phối hợp được sử dụng khi hai Danh tính cần thay đổi cùng nhau, ví dụ cổ điển là chuyển tiền từ tài khoản ngân hàng này sang tài khoản ngân hàng khác, nó cần chuyển hoàn toàn hoặc không.
Quyền truy cập không phối hợp được sử dụng khi chỉ có một Identity cần cập nhật, đây là trường hợp rất phổ biến.
Truy cập đồng bộ được sử dụng khi cuộc gọi dự kiến sẽ đợi cho đến khi tất cả Danh tính đã giải quyết xong trước khi tiếp tục.
Truy cập không đồng bộ là "cháy và quên" và để Danh tính đạt trạng thái mới trong thời gian riêng của nó.
ensure
hàm: clojure.github.io/clojure/clojure.core-api.html#clojure.core/… để làm cho điều này rõ ràng và hiệu quả hơn.
Refs dành cho trạng thái cần được đồng bộ giữa các luồng. Nếu bạn cần theo dõi nhiều thứ khác nhau và đôi khi bạn sẽ cần thực hiện các thao tác ghi nhiều thứ cùng một lúc, hãy sử dụng refs. Bất cứ lúc nào bạn có nhiều trạng thái khác nhau, sử dụng ref không phải là một ý kiến tồi.
Nguyên tử dành cho trạng thái độc lập cần được đồng bộ giữa các luồng. Nếu bạn không bao giờ cần phải thay đổi trạng thái của nguyên tử và bất kỳ thứ gì khác cùng một lúc, thì việc sử dụng nguyên tử là an toàn (đặc biệt, nếu chỉ có một trạng thái trong toàn bộ chương trình, bạn có thể đặt nó vào nguyên tử) . Như một ví dụ không nhỏ, nếu bạn đang cố gắng lưu vào bộ nhớ cache các giá trị trả về của một hàm (tức là ghi nhớ nó), thì việc sử dụng nguyên tử có lẽ là an toàn - trạng thái là vô hình với mọi thứ bên ngoài hàm, vì vậy bạn không cần phải lo lắng về sự thay đổi trạng thái bên trong hàm làm rối tung mọi thứ.
Điểm chính của đại lý là chúng chạy trong một chuỗi khác. Bạn có thể lấy giá trị của tác nhân và yêu cầu nó áp dụng một hàm cho giá trị của nó, nhưng bạn không biết khi nào hàm sẽ chạy hoặc giá trị nào mà hàm sẽ được áp dụng.
Vars dành cho khi bạn cần lưu trữ thứ gì đó trên cơ sở mỗi luồng. Nếu bạn có một chương trình đa luồng và mỗi luồng cần trạng thái riêng tư của nó, hãy đặt trạng thái đó trong một var.
Đối với các ví dụ trong thế giới thực, nếu bạn cung cấp ví dụ về những gì bạn đang cố gắng làm, chúng tôi có thể cho bạn biết bạn nên sử dụng những gì.
Khi tôi lần đầu tiên đọc về những loại này, tôi cũng đã đấu tranh để hiểu nơi tôi có thể hoặc nên sử dụng từng loại, vì vậy đây là câu trả lời đơn giản bằng tiếng Anh của tôi:
Sử dụng var khi dữ liệu không thay đổi. Điều này xảy ra bất cứ khi nào bạn sử dụng def
hoặc hầu hết các chức năng bắt đầu bằng def
like defn
.
Sử dụng nguyên tử khi bạn có một mục duy nhất thay đổi. Một ví dụ có thể là một bộ đếm hoặc một vectơ mà bạn muốn thêm các mục vào.
Sử dụng ref khi bạn có hai hoặc nhiều thứ phải thay đổi cùng một lúc. Hãy nghĩ đến "giao dịch cơ sở dữ liệu" nếu bạn đã quen thuộc. Ví dụ điển hình của việc này là chuyển tiền từ tài khoản này sang tài khoản khác. Mỗi tài khoản có thể được lưu trữ trong một ref để có thể thực hiện các thay đổi để có vẻ nguyên tử.
Sử dụng tác nhân khi bạn muốn thay đổi điều gì đó nhưng bạn không quan tâm khi nào. Đây có thể là một tính toán dài hoặc ghi một cái gì đó vào một tệp hoặc ổ cắm. Lưu ý rằng với cái sau bạn nên sử dụng send-off
.
Lưu ý: Tôi đánh giá cao rằng có khá nhiều thứ khác cho mỗi thứ nhưng hy vọng điều này sẽ cung cấp cho bạn một điểm khởi đầu.
Tôi đã viết một bài báo với tóm tắt sự khác biệt giữa chúng và giúp chọn khi sử dụng cái nào.
Chia sẻ trạng thái - khi sử dụng vars, nguyên tử, agent và refs?
Tôi hy vọng nó sẽ giúp mọi người tìm kiếm câu trả lời trong chủ đề đó.
Một số phím tắt từ bài viết sau gợi ý @tunaci:
Vars
Vars là toàn cầu cho mọi chủ đề.
Không thay đổi vars sau khi tạo. Về mặt kỹ thuật thì có thể, nhưng đó là một ý tưởng tồi vì nhiều lý do.
Nguyên tử
Chia sẻ quyền truy cập vào trạng thái có thể thay đổi cho mọi chủ đề. Thay đổi xảy ra đồng bộ. Thử lại khi luồng khác thay đổi trạng thái trong quá trình chạy.
Không sử dụng các hàm và hàm không phải là hàm đơn giản với thời gian thực thi lâu dài
Đại lý
Chia sẻ quyền truy cập vào trạng thái có thể thay đổi cho mọi chủ đề. Thay đổi xảy ra không đồng bộ.
Refs
Refs hoạt động tương tự như các giao dịch cơ sở dữ liệu. Viết và đọc được bảo vệ trong dosync. Bạn có thể thao tác trên nhiều refs an toàn trong giao dịch.
Và lưu đồ khi sử dụng cái nào:
Vui lòng xem hình ảnh trên trang web, vì luôn có thể cập nhật.
Nó là một chủ đề phức tạp và dài để đưa ra câu trả lời đầy đủ mà không có bài viết sao chép và quá khứ, vì vậy hãy tha thứ cho tôi, tôi đã chuyển hướng bạn đến trang web :)
nguyên tử, tham chiếu và tác nhân - một số ánh sáng ở đây http://blog.jayfields.com/2011/04/clojure-state-management.html
state-a
, nhưng tham khảo khistate-b
làm như vậy, tôi vẫn cần mộtref
chính xác? Vì vậy, không phải thay đổi nhiều thứ mà là đề cập đến nhiều thứ trong khi thay đổi bất kỳ thứ nào trong số chúng?