clojure - clojure 中比使用实例更惯用的模式?发送类型
问题描述
我尝试实现以下模式:我有一个 AST 和 2 个生成器,一个用于 C#,一个用于 VB。生成器将提供的 AST 作为输入,并以所选语言生成源代码。首先,我为生成器定义了一个抽象:
(defprotocol Generator
(generate-code [this ast]))
然后我给出一个实现,一个用于 C#,一个用于 VB(我将只给出 C# 实现,因为 VB 几乎完全相同):
(defn ^:private gen-csharp-class [ast]
(str "class " (:id ast) " { }"))
(defn ^:private gen-csharp [ast]
(cond
(instance? AstClass ast) (gen-csharp-class ast)))
(defrecord AGenerator []
Generator
(generate-code [this ast] (gen-csharp ast)))
我不喜欢instance?
在gen-csharp
函数中使用。在 Clojure 中编写这种类型的调度是否有更惯用的方式?
解决方案
您可以反转抽象:
(defprotocol CodeGenerator
(generate-class [this ast])
;; + other generator methods
)
(defrecord VBGenerator []
CodeGenerator
(generate-class [this ast] (gn-vb-class ast)))
(defrecord CSharpGenerator []
CodeGenerator
(generate-class [this ast] (gn-chsharp-class ast)))
然后instance?
只编写一次调用:
(defn gen-code [generator ast]
(cond (instance? AstClass ast) (generate-class generator ast)
;; + other generator cases...
))
或者您可以在 gen-class 的第二个参数上使用多方法。每个多方法定义都会从以下位置调用正确的方法CodeGenerator
:
(defmulti gen-class (fn [_ ast] (type ast)))
(defmethod gen-class AstClass [generator ast]
(generate-class generator ast))
推荐阅读
- string - 为什么我在字符串中找不到“read&tn=”?
- python - 为什么我的 if 和 elif 语句运行不正常?
- javascript - 反应中的切换路线不起作用,并且它不呈现页面。它改变了http链接但它不呈现页面?
- python - 使用 sklearn 从多个数据样本中整理概率、预测、系数
- google-drive-api - 有关访问链接共享文件的新安全更改的问题
- python - 解析时输入为文本的 Pandas 数字会添加一位小数并将数据类型显示为 float64
- php - 带有 WordPress 的多个 Bootstrap 5 缩略图轮播的 PHP 增量 ID
- android - 尝试在 kotlin 中使用 .startsWith() 和 .contains() 方法时出错
- python - 终端在不应该时接受键盘输入
- c - 汇编代码返回数组中值的总和