首页 > 代码库 > newLISP数据引用

newLISP数据引用

无法返回引用

数据传递包括两种,返回值和参数。

很可惜,newlisp的返回值只进行值拷贝,也就是返回副本,并没有方法返回引用。


那么看看参数吧,通过参数有两种方法传递引用,一种是通过使用单引号,比如:

单引号symbol传递参数引用

(define (change-list aList) (push 999 (eval aList)))

(set ‘data ‘(1 2 3 4 5))

; note the quote ‘ in front of data
(change-list ‘data)  → (999 1 2 3 4 5)

data  →  (999 1 2 3 4 5)

这种方法很简单,推荐使用。但是注意一个缺点:实参不能和形参名称相同。

> (set ‘aList ‘(a b c d))
(a b c d)
> (change-list ‘aList)

ERR: list or string expected : (eval aList)
called from user defined function change-list

通过context的default functor保存引用

context的default functor可以接受变参,因此可以将数据通过变参传递给context的default functor,加以保存

;; the default functor for holding data

(define Mylist:Mylist ‘(a b c d e f g))

(Mylist 3) → d 

(setf (Mylist 3) ‘D) → D

Mylist:Mylist → (a b c D e f g)

如果将Mylist保存到文件里面,可以看到:

(save "/opt/mm" ‘Mylist)

(context ‘Mylist)

(set ‘Mylist:Mylist ‘(MAIN:a MAIN:b MAIN:c MAIN:D MAIN:e MAIN:f MAIN:g))


(context MAIN)

通过context的default functor访问和改变数据

既然可以保存,就可以访问和修改。

(first Mylist) → a

(reverse Mylist) → (g f e D c b a)

(set ‘Str:Str "acdefghijklmnop") 

(upper-case Str) → "ACDEFGHIJKLMNOP"


通过context传递参数引用

是的,既然context是一个symbol,也可将其作为参数传递,只不过不需要前面用单引号来表示引用传递。

下面是通过default functor保存数据,然后将context作为参数传递给另一个函数

;; use a default functor to hold a list

(set ‘Mydb:Mydb (sequence 1 100000))

(define (change-db obj idx value)
    (setf (obj idx) value))

; pass by context reference
(change-db Mydb 1234 "abcdefg")

(Mydb 1234)  → "abcdefg"

通过context的symbol保存数据和传递参数引用

其实不一定非要default functor,context的symbol也行。

;; pass data by context reference

(set ‘Mydb:data (sequence 1 100000))

(define (change-db obj idx value)
    (setf (obj:data idx) value))

(change-db Mydb 1234 "abcdefg")

(nth 1234 Mydb:data)   → "abcdefg"
; or
(Mydb:data 1234)   → "abcdefg"

这种方法有个缺点,就是函数内部需要理解context的内部结构,比如例子中的obj:data.



newLISP数据引用