Неожиданное поведение функции `find` в Common-Lisp - PullRequest
3 голосов
/ 08 марта 2019

Поиск nil в последовательности с использованием find всегда возвращает NIL.

(find nil #(a b nil c)) -> NIL

(find nil #(a b c)) -> NIL

То же самое, если последовательность представляет собой список.

Однако, memberработает так, как я ожидал:

(member nil '(a b nil c)) -> (NIL C)

Почему find предназначен для такой работы?

Обратите внимание, что position работает так, как я ожидал:

(position nil #(a b nil c)) -> 2

(position nil #(a b c)) -> NIL

Ответы [ 2 ]

7 голосов
/ 08 марта 2019

FIND просто бесполезен, если целевым элементом является NIL.Он возвращает найденный элемент, но он неотличим от не найденного случая.Если вы хотите выяснить, в какой последовательности есть ноль, POSITION - лучший вариант.Есть много других вариантов.

1 голос
/ 09 марта 2019

Возвращает ноль, потому что результат поиска, если элемент отсутствует в последовательности, равен нулю. Но даже с member, если он не находится в последовательности, он вернет nil:

CL-USER> (member nil '(a b c))
NIL
CL-USER> 

Так что технически поиск nil в последовательности вернет nil с членом и позицией, если его там нет, что, конечно, может сбить с толку.

CL-USER> (position nil '(a b c))
NIL
CL-USER>

Разница с позицией заключается в том, что если возникнет ноль, то, как вы заметили, он вернет местоположение индекса. Find был разработан таким образом, потому что он НЕ ищет местоположение индекса, но, по сути, ищет, чтобы найти указатель на этот символ или вернуть nil. Вот почему использование позиции имеет больше смысла, как вы заметили.

...