我学习计划(使用guile),我发现需要创建一个初始列表,其中包含一些键和空列表作为其值。我想知道在做这样的事情时最好的做法是什么。我的目标是保持这种状态,以便稍后我可以将项目添加到列表中。这就是我现在所拥有的:
(define buckets
`((hourly . ())
(daily . ())
(monthly . ())
(yearly . ())))
但是,在尝试assoc-set!
时,将项目附加到列表时,这不起作用。然而,这有效:
(define buckets
(acons 'hourly '()
(acons 'daily '()
(acons 'monthly '()
(acons 'yearly '() '())))))
显然不是最好看的代码。是否有更惯用的方式来建立这样的列表?也许我完全错了。最终目标是拥有这些桶,我可以通过它们的密钥在后面的代码的不同部分引用它们。
谢谢!
答案 0 :(得分:0)
scheme@(guile-user)> (acons 'hourly '()
(acons 'daily '()
(acons 'monthly '()
(acons 'yearly '() '()))))
$2 = ((hourly) (daily) (monthly) (yearly))
与
相同scheme@(guile-user)> '((hourly) (daily) (monthly) (yearly))
$3 = ((hourly) (daily) (monthly) (yearly))
scheme@(guile-user)> (equal? $2 $3)
$4 = #t
编辑 assoc-set!
在这种情况下不起作用,因为这些列表不可变。实现可变列表同时仍然缩短定义方式的一种方法是使用此表达式:
(map list '(hourly daily montly yearly))
答案 1 :(得分:0)
我的回答是在Scheme中,但很容易被翻译成guile
如果你想要一个高级解决方案,你可以采用一种方法,一旦完成,它将为你提供一个抽象层和更容易的数据管理。
迈出对象建模的一步!
根据行为(您支持的方法集),您希望自己的对象具有,通常应该如下所示:
(define make-state-manager
(lambda()
(let ((data_lst '()))
(letrec
((get-lst (lambda (key) (assoc key data_lst)))
((get-data (lambda (key) (assoc-ref key data_lst)))
((add-item (lam ...)
... here you should have add-data , remove-data etc.
(action_n ....)
(dispatch (lambda (action)
(cond ((eq? action ’full-list) get-lst)
((eq? action ’value) get-data)
((eq? action ’add-to-list) add-item)
...
((eq? action ’action_n) func_n)
(else (error "Unknown request: ~s" action)))))
)
dispatch))
))
...)))
用法:
>(define data_manager (make-state-manager))
> data_manager
> #<procedure... >
> ((data_manager 'add-data) 'hourly '())
> ((data_manager 'value) 'hourly)
> ()
> ((data_manager 'full-list) 'hourly)
> (hourly . ())
说明: 首先,让我们创建一个本地状态,以便您可以运行
(define data_manager1 (make-state-manager))
(define data_manager2 (make-state-manager))
他们将拥有不同的范围,这些行动不会相互影响。
然后在letrec中使用您的方法名称定义对象方法。
在发送(向用户发送:)中,您可以设置用户将使用的方法名称。
来源:我的大脑&amp;这个疯狂的book如果这让你的思绪太过沉重 - 稍后再回来......