2009-03-10 32 views
13

Bất cứ ai có thể cho tôi biết cách làm việc với các thông số được lưu trữ trong giá trị được chỉ định bởi & nghỉ ngơi.Common Lisp: Làm việc với các tham số còn lại

Tôi đã đọc rất nhiều và dường như các tác giả chỉ biết cách liệt kê tất cả các tham số như vậy.

(defun test (a &rest b) b) 

Điều này rất thú vị nhưng không thực sự hữu ích.

Điều tốt nhất tôi đã tìm thấy cho đến nay là sử dụng đầu tiên, thứ hai, v.v. để có được thông số bạn đang tìm kiếm.

(defun test (a &rest b) 
    (first b)) 

tôi nhận thấy phương pháp này ngừng hoạt động tại các tham số thứ mười, nhưng đặc điểm kỹ thuật (từ những gì tôi đã đọc) hỗ trợ tối thiểu là 50. Ngay cả khi rất có thể là mỏng mà tôi sẽ sử dụng 50 thông số, tôi muốn biết cách truy cập tất cả.

Cảm ơn

Trả lời

6

Chức năng truy cập FIRST, SECOND và như vậy là "chỉ" các chức năng tiện ích ở trên cùng của CAR/CDR hoặc NTH. SO, tôi đoán, câu trả lời cho câu hỏi cụ thể của bạn là "sử dụng NTH hoặc ELT" (hoặc xây dựng các hàm acccessor cụ thể của riêng bạn).

Nếu bạn muốn, bạn có thể xác định một thứ XI như:

(defun mười một (danh sách) (thứ n danh sách 10))

tôi thấy, tuy nhiên, tôi chủ yếu sử dụng & luận REST của khi có 0 hoặc nhiều thứ tôi muốn làm gì đó, không thực sự quan tâm đến vị trí cụ thể của một đối số đã cho trong danh sách REST & REST. Điều đó thường đòi hỏi phải sử dụng LOOP, DO hoặc DOLIST để duyệt qua các đối số và làm điều gì đó với mỗi đối số; họ MAP ​​hoặc (thỉnh thoảng) GIẢM.

8

Thông số còn lại chỉ là một danh sách. Bạn có thể xử lý nó bằng cách sử dụng các hoạt động danh sách bình thường.

(defun test (a &rest b)) 
    (dolist (s b) 
    (when (> s 1) 
     (print s) 
     (do-something-else b))) 
+0

Đó là một danh sách bên trong hàm, nhưng việc chuyển danh sách thành & phần còn lại có thể không cung cấp cho bạn hành vi mà bạn muốn (trái với params [] từ ngôn ngữ C#). Khá dễ dàng đối với người mới bắt đầu (như bản thân tôi) để thực hiện sai lầm này: giả sử hàm của bạn đệ quy với tham số & tham số còn lại. Sau đó, trong quá trình đệ quy, bạn không thể chuyển danh sách thành tham số & tham số còn lại, bạn phải sử dụng # 'yourfun ... – PawelP

+1

@PawelP Nếu bạn cần chuyển danh sách, thì chỉ cần sử dụng hàm param thông thường để chuyển danh sách đó. & tham số còn lại chỉ là một cách dễ dàng để gọi hàm với số biến số tham số mà không cần gói chúng trong danh sách trên mỗi trang gọi. – Marko

+0

Điều gây hiểu lầm cho tôi là thực tế là * bên trong * chức năng, & tham số còn lại được truy cập giống như danh sách, tuy nhiên bạn không thể truyền trực tiếp nó như một tham số & phần còn lại đệ quy (vì bạn đang chuyển danh sách và có lẽ không phải những gì bạn muốn). Tôi nghĩ tôi không phải là người mới bắt đầu duy nhất rơi vào cái bẫy này. Vì vậy, có vẻ như LISP làm một số "đóng gói" đằng sau hậu trường về lời gọi hàm (làm cho một danh sách trong số các tham số được phân tích thành & phần còn lại) Tất nhiên giải thích của bạn là chính xác, tôi không tranh chấp điều đó. – PawelP

5

Thực ra chức năng này rất hữu ích. Bạn chỉ phải thử nó.

CL-USER 1 > (defun test (a &rest b) b) 
TEST 

CL-USER 2 > (test 1 2 3 4) 
(2 3 4) 

Vì vậy, bạn thấy rằng B chỉ là danh sách các đối số. Vì vậy, mọi hoạt động danh sách và chuỗi đều được áp dụng. Không có phép thuật gì cả. Có chức năng để truy cập các yếu tố NTH, chức năng để loại bỏ các yếu tố, vv ..

Trong Common Lisp HyperSpec các chức năng có liên quan được liệt kê:

14. The Conses Dictionary

17. The Sequences Dictionary

Đối với một Lisp cơ bản hướng dẫn kiểm tra cuốn sách của Touretzky:

Common Lisp: A Gentle Introduction to Symbolic Computation

Sách có thể tải xuống bằng PDF và Postscript. Nó dạy Basic Lisp cơ bản.

+0

Cảm ơn bạn đã liên kết đến phần giới thiệu nhẹ nhàng. Tôi đã duyệt qua vài chương đầu tiên và tôi phải nói rằng tôi thực sự muốn đây là cuốn sách lập trình đầu tiên tôi đọc. Nó được thực hiện rất tốt. – BlueBadger

3

Bạn cũng có thể sử dụng destructuring-ràng buộc:

(defun my-function (&rest arguments) 
    (destructuring-bind (a b &rest c) arguments 
    (format nil "~A,~A followed with ~A" a b c))) 

CL-USER> (my-function 1 2 "Give" 'me "more" 'arguments!!) 
==> "1,2 followed with (Give ME more ARGUMENTS!!)" 
0

tôi chỉ có một lặp đệ quy để đi qua tất cả, tôi đoán dolist là tốt hơn nhưng tôi thích sử dụng theo cách cũ thời

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