2012-02-20 35 views
8

Tôi đang viết một số phương pháp để phát ra HTML cho các phần tử khác nhau. Mỗi phương thức có cùng một đầu ra, nhưng không nhất thiết cần cùng một đầu vào.Đối số tùy chọn trong defgeneric?

Phương pháp lặp lại một game-board nhu cầu để có một player cũng (vì mỗi người chơi chỉ nhìn thấy những mảnh riêng của họ)

(defmethod echo ((board game-board) (p player)) ...) 

Vang vọng một không gian bảng không yêu cầu thay đổi mỗi player (công văn đó là thực sự được thực hiện theo phương pháp game-board, sau đó gọi echo trên một không gian). Lý tưởng nhất, tôi có thể làm

(defmethod echo ((space board-space)) ...) 
(defmethod echo ((space empty-space)) ...) 

Nó cũng có thể hiểu được rằng sau này tôi cần phải biết nhiều hơn chỉ là trình phát để hiển thị chính xác. Do đã có phương pháp chuyên về cùng chung chung, mặc dù, rằng sẽ cung cấp cho các lỗi

The generic function #<STANDARD-GENERIC-FUNCTION ECHO (4)> takes 2 required arguments; 

Dường như ít hơn lý tưởng để quay trở lại và đặt tên cho những phương pháp echo-space, echo-board và vân vân.

Có một cách hợp lý để thay đổi các đối số khác dựa trên đối tượng chuyên biệt không? Tôi có nên làm điều gì đó như

(defgeneric echo (thing &key player ...) ...) 

hoặc

(defgeneric echo (thing &rest other-args) ...) 

? Nói chung, bất cứ ai có thể chỉ cho tôi một hướng dẫn phong nha trên defgeneric cụ thể? (Tôi đã đọc các chương PCL có liên quan và some CLOS tutorials, nhưng chúng không bao gồm tình huống mà tôi đang hỏi ở đây).

Trả lời

5

Nói chung nếu giao diện của hai hàm quá khác nhau, nó chỉ ra rằng chúng không thực sự là một chuyên môn của cùng một thao tác và không nên có cùng tên. Nếu bạn chỉ muốn chuyên về các đối số tùy chọn/khóa, cách để đạt được điều đó là sử dụng một hàm bình thường gọi hàm chung và cung cấp nó với các giá trị mặc định cho các đối số bị thiếu để chuyên về.

Keene's book là, tôi tin rằng, hướng dẫn toàn diện nhất cho CLOS. Thật không may, nó dường như chỉ có sẵn ở dạng sách.

+0

Có một công văn chức năng trên một chung chung có vẻ ít hơn đáp ứng (mà có đất tôi trở lại trong lãnh thổ 'echo-board' /' echo-space'/etc). Tôi nghĩ bạn đúng trong trường hợp này; Tôi có thể được tốt hơn off xác định một cái gì đó như 'echo' (để sản xuất đơn độc đáo) và một' echo-phù hợp' riêng biệt hoặc tương tự (mà sẽ thay đổi sản lượng của nó dựa trên các thông số bổ sung). – Inaimathi

+0

Hàm không chung chung không thực hiện công văn, nó chỉ chuẩn hóa các đối số. Điều này rõ ràng đòi hỏi các chung chung (và vì vậy các phương pháp) để có tất cả các đối số có thể, đó là lý do tại sao điều này chỉ hữu ích khi giao diện thực sự là tương tự. – Ramarren

+0

Đây là một tập tin PDF của cuốn sách Keene (Tôi không biết về cách thức này là hợp pháp, xin vui lòng tư vấn): https://doc.lagout.org/programmation/Lisp/Object-Oriented%20Programming%20in%20Common%20Lisp_% 20A% 20Programmer% 27s% 20Guide% 20to% 20CLOS% 20% 5BKeene% 201989-01-11% 5D.pdf –

0

Điều gì về việc tái cơ cấu các đối tượng/lớp học sao cho mỗi đối tượng bạn muốn lặp lại có tất cả các thuộc tính bắt buộc trong các vị trí riêng (và được kế thừa) của nó?

Bằng cách đó bạn không phải chuyển chúng làm đối số khi bạn gọi echo trên đối tượng, vì những gì bạn cần đã được lưu trữ trong đối tượng.

3

Sẽ dễ dàng hơn bất cứ khi nào các phương thức thực hiện cùng các tham số nhưng chỉ khác nhau về kiểu dữ liệu. Nhưng trong trường hợp tất cả các hàm và phương thức chung đều sử dụng cùng tên (dĩ nhiên) nhưng có danh sách lambda khác nhau đáng kể, cá nhân tôi có xu hướng sử dụng thông số chính & để làm rõ ý định của tôi, thay vì sử dụng thông số & tùy chọn. Tôi nghĩ rằng nó sẽ giúp với khả năng đọc sau này.

Hãy thử một cái gì đó như thế này (giả vờ chúng ta đã có các lớp học đẳng cấp a và đẳng cấp b):

(defgeneric foo (object &key &allow-other-keys) 
    (:documentation "The generic function. Here is where the docstring is defined.")) 

(defmethod foo ((object class-a) &key &allow-other-keys) 
    (print "Code goes here. We dispatched based on type Class A.")) 

(defmethod foo ((object class-b) &key (x 1) (y 2) &allow-other-keys) 
    (print "Code goes here. We dispatched based on type Class B. We have args X and Y.")) 

Vì "phương pháp kết hợp" có liên quan, để cho các logic điều phối để "dòng chảy" thông qua của nó có thể lựa chọn các phương pháp để sử dụng, chúng ta cần nghĩ về các định nghĩa phương thức phần nào giống như một chuỗi trong đó các danh sách lambda không tương thích (ví dụ các danh sách tham số) sẽ phá vỡ chuỗi đó. Đó là lý do tại sao có các phím & và & các khóa cho phép khác trong định nghĩa phương thức mà không cần chúng cụ thể. Đặt chúng trong DEFGENERIC và định nghĩa phương thức cho phép chúng ta có định nghĩa phương thức mà chúng ta gửi dựa trên lớp-b.

TUYÊN BỐ TỪ CHỐI: Tôi là một người mới chơi Lisp thường gặp, vì vậy hãy dùng nó với một hạt muối!

Các vấn đề liên quan