newlisp dotimes循环 与 整数格式化成字符串

dotimes循环类似于其他语言的for循环,迭代从0到n-1.

下面是官方文档。

dotimes

syntax: (dotimes (sym-var int-count [exp-break]) body)

The expressions in body are evaluated int times. The variable in sym is set from 0 (zero) to (int - 1) each time before evaluating the body expression(s). The variable used as the loop index is local to the dotimes expression and behaves according the rules of dynamic scoping. The loop index is of integer type. dotimes returns the result of the last expression evaluated in body. After evaluation of the dotimes statement sym assumes its previous value.

Optionally, a condition for early loop exit may be defined in exp-break. If the break expression evaluates to any non-nil value, the dotimes loop returns with the value of exp-break. The break condition is tested before evaluating body.

(dotimes (x 10)
  (print x))   9  ; return value

This prints 0123456789 to the console window.


文档中有一个没有说明,就是int-count参数求值只做一次,不会每次循环之后都会重新求值。

下面有个简单测测试例子:
> (dotimes (n (begin (print "x") (+ 1 1))) (print "ok"))
xokok"ok"

x只打印了一次。这个特性理解很重要,比如我有个函数,将10进制整数转换成16进制字符串,然后计算长度,如果不够4位,则前面补0.
;; size is the length of returned hex string
;; if the length of formatted value is less than size,
;; a few "0" characters will be inserted in front of the string
(define (hex-str int-val size)
  (let (v (format "%X" int-val))
    (if (< (length v) size)
	(dotimes (n (- size (length v)))
		 (push "0" v))
	v)))

运行一下:
> (hex-string 4 4)
"0004"

主要是因为每次v都会被添加一个字符"0",因此dotimes只求值一次的特性才不会干扰我的逻辑。

在这个例子中,还用到了format来格式化字符串,和C的printf相同的功能。怀疑就就用printf实现的。


你可能感兴趣的:(newlisp dotimes循环 与 整数格式化成字符串)