0%

Elisp Basics

闲话

有很长时间没写Blog了,主要原因是,不够自律,没有坚持写下去,次要原因是,最近确实是忙了些,几乎每周都有一多半的时间是在下班的,由于这样的疲累,也导致了一旦不上班的时候就忙着休息了。

有时想想,其实忙并不是放松的理由,最主要的原因还是因为懒,这个是一定要改的,再不改我们就老了。

最近做了几件事,首先当然还是工作,游戏有前端进步非常大,与半年前相比几乎完全变成了另外一个游戏的感觉,加入了新角色,玩法系统也更丰富了,对于我负责的后端,除了加新功能,其它的变化并不大,但是有计划对架构底层的Cache系统进行改进,这将很大的提高系统的性能和稳定性;另外的事就是,关掉了LinodeVultr主机,当然了,这跟这两家的服务质量无关,主要是我为合理调配资源。首先,开了一台AWS用来做佛跳墙的主力服务器,另外开了一台香港的主机用来放BLOG和小项目,而且同时在搬瓦工DigitalOcean还各有一台VPS做备用的科学上网服,所以,这个时候还留着LinodeVultr就是极大的浪费了吧。不过话说回来,这两家的东京服务器对于国内来说还是相当不错的,也就只比香港机房差一点吧。

Emacs & Elisp

从使用Emacs开始到现在也有个几年了吧,不过大多数时间都是在别人配置的基础上进行修改,而且在Emacs上时多半都是一些中小型的开发和写作,这样的应用场景下,自然对于Emacs的配置要求就没有那么高了。趁着这段时间没什么学习新知识的想法,刚好可以再次拿起Emacs以及必须要掌握的Elisp好好学习一番了。

因为之前对Common Lisp有过一定程度上的了解,所以对于Elisp其实接受起来还是挺快的,在简单看了几篇关于Elisp的文章后,对于Elisp的大概印象也就有一些,在这里仅对Elisp做一个简单的介绍,备忘吧。

Printing

  • message
    此函数用于输出信息到缓冲区*Messages*,并支持格式替换,如下:

    1
    2
    3
    4
    5
    (message "hello") ; 最简单的输出
    (message "hello, my age is %d" 35) ; %d接受一个数字
    (message "my name is %s" "Toby") ; %s接受一个字符串
    (message "a new list: %S" '(1 2 3)) ; %S 接受一个Lisp表达式
    ;; 在格式字符串中还支持%X,%x等。
  • print/prin1
    本函数用于输出一个Lisp对象,两者的区别是,prin1不输出新行

    1
    2
    (print "HELLO")
    (prin1 "HELLO")
  • princ
    输出对人类友好的内容

    1
    2
    (princ "hello") ; => hello
    (print "hello") ; => "hello"
  • format
    接受一个格式字符串和多个参数,返回字符串。

    1
    (print (format "hello %s" "world))

关于输出,还可以指定输出到的缓冲器或者输出到当前Buffer等,在这里就不细说了。

数学运算

Elisp支持所有的常见数学运算,如加减乘除等,以下只做举例

1
2
3
4
5
6
7
8
(+ 1 2) ; => 3 加
(- 2 1) ; => 1 减
(* 2 6) ; => 12 乘
(/ 6 2) ; => 3 除
(/ 5 2) ; => 2 int相除取整数部分
(/ 5 2.0) ; => 2.5 浮点型除法
(% 9 6) ; => 3 取余
(expt 3 3) ; => 27 乘方

另外,还有一些判断数据类型的函数,如

1
2
3
(integerp 3.) ; => t 判断是否为整型
(floatp 3.) ; => nil 是否为浮点型
(floatp 3.0) ; => t

注:在Elisp中,在数字的点后面如果没有其它数字(包括0),则认为这个数字为整型。

Boolean and Functions

在Elisp中,只有nil()为False,其它的都为True。同时,Elisp是支持逻辑或和逻辑与操作的,如下:

1
2
(and t nil) ; => nil
(or nil t) ; => t

数字关系比较函数

1
2
3
4
5
6
7
(> 3 4)
(< 3 4)
(>= 3 4)
(<= 3 4)
(= 5 5)
(= 5 5.0)
(/= 5 6) ; 不等于,其它的关系不做解释,但是不等于函数与其它语言完全不同,一定要牢记

字符串专用比较函数

1
(string-equal "hello" "hello) ; => t,比较字符串内容

通用比较函数

对参数的数据类型及其值进行比较,只有全部相同时才为True

1
2
3
(equal "abc" "abc") ; => t
(equal 3 3) ; => t
(equal '(1 2 3) '(1 2 3)) ; => t

独特的比较函数eq

此函数比较参数是否为相同对象

1
2
(eq "abc" "abc") ; => nil 此函数要与equal和string-equal区分开,两个字符串显然不是同一个对象
(eq 'abc 'abc) ; => t

逻辑取反

1
(not t) ; => nil

变量

全局变量

两种设置方式,变量的值可以是Elisp支持的任何类型

1
2
(setq x 1) ; => 将x设置为1
(setq x 1 y 2 z 3) ; => 将x设为1,y设为2, z设为3

局部变量

局部变量的初始化有两种方式,如下

1
2
3
4
5
6
7
8
9
(let (x y)
(setq x 1)
(setq y 2)
(+ x y)
) ; => 3 初始化方式1

(let ((x 1) (y 2))
(+ x y)
) ; => 3 初始化方式2

很显然,当变量为固定的值时,第2种初始化方式更便捷一些。

(TO BE CONTINUE)

Welcome to my other publishing channels