Lisp中的函数

定义新函数

以下为函数的定义形式

(defun name (parameter*)
    "body"
    )
  • 通常,函数的命名仅包含字典字符和连字符

  • 如果一个字符串跟在形参的后面,那么它应该是一个描述函数用途的文档字符串

  • 函数主体将会返回最后一个表达式的值,可以实用RETURN-FROM特殊操作符可用于立即返回

可选形参

;在固定参数的后面加上optional表示后面的参数为形参
(defun name (a b &optional c)
    (format t a+b)
    )

也可以使用列表的形式来提供默认值

(defun name (a b &optional (c 10))
    (list a b c)
    )
(defun hello(a b &optional (c 10))
  (list a b c)
)

如果想要基于其他形参计算默认值,默认值可以引用前面已经应用的了的形参

(defun hello(a b &optional (c a))
    (list a b c)
    )

如果想要判断一个可选参数究竟是被调用者明确制定了某个值,还是实用了默认值,可以在默认表达式之后添加一个变量,这个变量将在调用者实际调用了之后返回T,否则为NIL,这种变量与对应的实参名字相同,但是需要添加一个-supplied-p后缀

(defun hello (a b &optional (c 10 c-supplied-p))
    (format t a b c)
    )

剩余形参

如果使用了&rest,那么该当函数调用满足了必要形参和可选参数之后,其余形参将被收集到一个列表里成为该&rest形参的值

关键字形参

可以实用关键字形参&key的方式来指定为哪个形参复制

(defun hello (&key a b c)
    (list a b c)
    )

关键字是以:被自动定义成自求值变量

(hello :a 3)
;3 NIL NIL

混合参数

  • 使用&optional和&key的混合可能会产生奇怪的效果,因此在这种情况下最后就实用&key即可

  • 如果混合了&key和&rest,那么除了必要参数和可选参数之外,其余参数既会被绑定到key上,也会被绑定到rest上

函数返回值

使用return-from是一个特殊操作符,其第一个“参数”是它想要返回的代码块名。该名字不被求值,因此无需引用

(defun foo (n)
    (dotimes (i 10)
        (dotimes (j 10)
            (when (> (* i j) n)
                (return-from foo (list i j))))))

作为数据的函数

特殊操作符FUNCTION可以用来获取一个函数对象,它接受单一实参并返回与该参数同名的函数。这个名字是不被引用的

;定义函数
(defun hello () (format t "hello"))

;获取函数对象
(function hello)

;可以实用#'同样来获取函数对象
#'hello

;实用funcall来调用函数对象,与(hello)是一样的效果
(funcall (function hello))

匿名函数

如果想要创建一个只需要使用一次的函数,可以使用匿名函数来进行创建

(lambda (parameters) body)

lambda表达式可以用在任何正常函数名出现的地方

;使用函数
((lambda (x y) (+ x y)) 2 3)

;使用#‘获取函数对象
(funcall #'(lambda (x y) (+ x y)) 2 3)
© 版权声明
THE END
喜欢就支持以下吧
点赞0
分享
评论 抢沙发
四曲的头像-四曲博客

昵称

取消
昵称表情代码图片