coding-style - 请求有关代码风格/最佳实践的输入
问题描述
我正在尝试通过遵循 Java 中的这种实现(https://craftinginterpreters.com/control-flow.html)在 Common Lisp 中实现一种编程语言。
真正令人烦恼的一件事是到处都有大量的槽值。
当然,我可以在每个带有插槽的函数中添加一行,但这也是重复的,并且考虑到我的符号不是 :used 但我在包中引用它们,因为许多模块中有很多符号而我没有不想忘记它们的来源,即使 with-slots 也需要完整的限定名称。在我看来,这一切都像是非常糟糕的代码气味。
我用谷歌搜索并找到了rutils。使用它的@object.slot 访问器,我设法极大地清理了我的代码。只需查看最后一次提交https://github.com/AlbertoEAF/cl-lox/commit/84c0d62bf29bff9a2e0e77042a9108c168542b96?diff=split摘录:
(我可以粘贴代码,但所有代码都可以在那个 repo 上找到,我想显示差异亮点)
它不仅删除了一些字符,而且更重要的是,需要考虑的深度(槽值调用)和括号的级别减少了 - 这对琐碎的功能有很大帮助。
当我有很多很多符号名称并且由于我开始在符号中发生冲突而无法全部导出它们时,情况会变得更糟。
你们能给我输入代码吗?现在看起来好多了,但我很好奇,好像有更好的方法来解决它?
谢谢!
解决方案
在类定义中定义访问器函数还可以节省一些输入,而不必使用非标准语法
如果你像这样定义一个 CLOS 类:
(defclass person ()
((name
:initarg :name)))
(defparameter *p* (make-instance 'person
:name "John"))
访问name
slot in的 slot 值的唯一方法*p*
是:
(slot-value *p* 'name)
;; "John"
(with-slots (name) *p*
name)
;; "John"
(with-slots ((nm name)) *p*
nm)
;; "John"
但是,如果您为每个插槽定义 an :accessor
,则可以使用作为参数给出的函数名称,:accessor
而不必使用slot-value
orwith-slots
来访问和改变它(setf
-able!)。
(defclass person ()
((name
:initarg :name
:accessor nm)))
(nm *p*)
;; "John"
(setf (nm *p*) "Doe")
;; "Doe"
(nm *p*)
;; "Doe"
然而,约定是,将插槽名称也用作:accessor
方法的名称:
(defclass person ()
((name
:initarg :name
:accessor name))) ;; but better use the slot name as accessor
(name *p*)
;; "John"
(setf (name *p*) "Doe")
(name *p*)
;; "Doe"
该:accessor
方法(泛型函数)特定于此类的对象。因此,您不必担心名称空间冲突。
(defclass house ()
((address
:initarg :address
:accessor addr)))
;; you cannot use `address` because it is already occupied
;; by a system's function/symbol -> see under `(describe 'address)`
(defparameter *h* (make-instance 'house :address "Bakerstreet 1"))
(name *h*)
;; EVAL: undefined function name OR:
;; NO-APPLICABLE-METHOD error (in the case
;; that other classes exist with a `name` accessor method.
(addr *h*)
;; "Bakerstreet 1"
(addr *p*)
;; *** - NO-APPLICABLE-METHOD: When calling #<STANDARD-GENERIC-FUNCTION ADDR>
;; with arguments (#<PERSON #x1B06B79E>), no method is applicable.
;;
推荐阅读
- flutter - Flutter中如何根据平台编译源码?
- javascript - 解析云代码作业功能优化
- javascript - Cordova -> face-api-js [错误] 加载资源失败:在此服务器上找不到请求的 URL。(空,第 0 行)
- sql - 转换 PostgreSQL 中的时间戳数组(不在表中)
- r - 创建具有最大值的新列
- react-native - 如何验证 AsyncStorage 在 react-native 中是否可用
- python - .plot() 保留旧图并每次在其上绘制新图
- html - TikZJax 生成的 svg 中的一些数学符号渲染不正确
- postman - 邮递员 - 未在正文的预览选项卡上呈现响应 - 仅显示一个小缩略图
- python - 查找数组对 (a,b) 的数量,其中 abs(ab) = k in O(n)