关于emacs:如果是语句/字符串比较

If statement / String comparison

我对elisp还不熟悉,正试图用if语句编写一个简单的程序。

重点是在一年的学习中阅读,并在没有匹配时分别返回12340字符串"freshman""sophomore""junior""senior"(默认为0)。我的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(defun yearCode(name)
    (if ( = name"freshman") 1
      (if ( = name"sophomore") 2
        (if ( = name"junior") 3
          (if ( = name"senior") 4
            (0))))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; main function                        ;;;
;;; input: year                          ;;;
;;; output: code corresponding to year   ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun main (year)
 (interactive"sEnter your academic year:")  ; read year
 (message"%d" (yearCode year)))              ; display its code

  ;;; Tests...
 (main"junior")
 (yearCode"junior")

我真的对elisp一无所知,所以我甚至在编译第一部分时也遇到了困难。有人能帮我正确地构造一个if语句吗?

编辑:我在错误的缓冲区中进行测试——代码使用if语句工作。


当您在Ruby中使用if..elseif..elseif..else时,在Emacs Lisp中使用cond

1
2
3
4
5
6
(defun yearCode (name)
  (cond
   ((string= name"freshman") 1)
   ((string= name"sophomore") 2)
   ((string= name"junior") 3)
   ((string= name"senior") 4)))

不过,我不会这么写的。

1
2
3
4
5
6
(defun yearCode (name)
  (cdr (assoc name
              '(("freshman" . 1)
                ("sophomore" . 2)
                ("junior" . 3)
                ("senior" . 4)))))

有很多种平等,而=严格用于数字(或标记)。string=用于字符串和字符串指示符,eq用于对象标识,equal是一种元素的深度相等(这就是它适用于字符串的原因,但它只会在字符串与非字符串比较时返回false,而不会检测到错误)。后者,即equal,由assoc使用。


用最小的更改编写yearCode的方法是:

1
2
3
4
5
6
(defun yearCode (name)
  (cond ((string= name"freshman") 1)
        ((string= name"sophomore") 2)
        ((string= name"junior") 3)
        ((string= name"senior") 4)
        (0)))

编辑添加:问题的原始版本结构非常不同,因此下面的解释不再适用…

您所写的代码与上面的代码的区别在于,在上面的代码中,yearCode有一个(cond表达式),该函数的返回值是cond语句的返回值。

您的原始代码有4个不同的表达式,只有最后一个表达式的值被实际返回(最后一个if语句),这意味着返回值是4nil

我建议你读一本介绍性的Lisp书,我最喜欢的是sicp,但是你可能应该去看看so的问题,寻找最好的介绍性书籍。


这将是使用if语句编写它的方法。if语句有一个条件部分,该部分为真或假。如果为真,则对第一部分进行评估。它实际上只能是一个句子,除非使用(progn )。其余部分将是if语句的其他部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
(defun yearCode(name)
    (if (string= name"freshman")    ; true or false?
       1                            ; if true, returns 1

  ; Note that you can't really write anything else here.
  ; From here on, it is the first else part!

     (if (string= name"sophomore")  ; if false, else part  etc.
       2
      (if (string= name"junior")
        3
       (if (string= name"senior")
         4)))))

虽然这明确回答了你关于if的问题,但我还是建议使用cond,就像其他人建议的那样。

在应用progn的情况下,如果为真,则要对1个以上的表达式进行评估。

1
2
3
4
5
6
7
8
9
10
11
(defun yearCode(name)
    (if (string= name"freshman")    ; true or false?
       (progn 1                      ; if true, returns 1
              (message"this is possible!"))          

     (if (string= name"sophomore")  ; if false, else part  etc.
       2
      (if (string= name"junior")
        3
       (if (string= name"senior")
         4)))))