Вопрос

Кто-нибудь может подсказать мне, как работать с параметрами, хранящимися в значении, указанном &rest.

Я много читал, и кажется, что авторы знают только, как перечислить все параметры таким образом.

(defun test (a &rest b) b)

На это приятно смотреть, но на самом деле не так уж и полезно.

Лучшее, что я нашел на данный момент, - это использовать first, second и так далее, чтобы получить искомый параметр.

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

Я заметил, что этот метод перестает работать при десятом параметре, но спецификация (из того, что я прочитал) поддерживает минимум 50.Даже если шансы на то, что я буду использовать 50 параметров, невелики, я хотел бы знать, как получить доступ ко всем из них.

Спасибо

Это было полезно?

Решение

ПЕРВАЯ, ВТОРАЯ и так далее функции доступа - это "просто" служебные функции поверх CAR / CDR или NTH.ИТАК, я полагаю, ответ на ваш конкретный вопрос таков: "используйте NTH или ELT" (или создайте свои собственные специфические функции acccessor).

Если вы хотите, вы можете определить ОДИННАДЦАТЫЙ как:

(обезврежен одиннадцатый (список) (n-й список из 10))

Однако я обнаружил, что в основном использую аргументы &REST, когда есть 0 или более вещей, с которыми я хочу что-то сделать, на самом деле не заботясь о конкретной позиции данного аргумента в списке &REST.Обычно это влечет за собой использование LOOP, DO или DOLIST для обхода аргументов и выполнения чего-либо с каждым из них;семейство карт или (иногда) УМЕНЬШИТЬ.

Другие советы

Параметр Rest - это просто список.Вы можете справиться с этим, используя обычные операции со списком.

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

На самом деле эта функция полезна.Вам нужно только попробовать это.

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

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

Итак, вы видите, что B - это просто список аргументов.Таким образом, применимы все операции со списком и последовательностью.Здесь нет ничего волшебного.Существуют функции для доступа к N-му элементу, функции для удаления элементов и т.д..

В Common Lisp HyperSpec перечислены соответствующие функции:

14.Словарь Conses

17.Словарь Последовательностей

Базовое руководство по лиспу можно найти в книге Турецкого:

Обычный шепелявый:Краткое введение в символьные вычисления

Книгу можно загрузить в формате PDF и Postscript.Он обучает основам Common Lisp.

Вы также могли бы использовать destructuring-bind:

(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!!)"

У меня просто есть рекурсивная итерация, чтобы просмотреть их все, я думаю, dolist лучше, но мне нравится использовать старомодный способ

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top