基于 Go 的 Clojure
在你的浏览器中尝试!Gopher 图像由 @egonelbre 提供,采用创意共享 1.0 署名许可。Glojure 是一个在 Go 上托管的 Clojure 解释器。Glojure 提供对 Go 库的简单访问,类似于 Clojure 对 Java 框架的简单访问。Glojure 处于初期开发阶段;请期待错误、缺失功能和有限的性能。在 v1 发布之前不保证向后兼容。不过,它已成功用于个人项目,并运行了 (转换后的) 核心 Clojure 库的一个显著子集。请注意,与大多数其他 Go 实现的 Clojure 不同,Glojure 是一种“托管”语言——这一术语用于描述以某种宿主语言(在本例中为 Go)实现的语言。这意味着所有 Go 值都可以作为 Glojure 值使用,反之亦然。入门前的准备 在开始使用 Glojure 之前,请确保您已安装并了解 Go (1.19 版本或更高)。安装 Glojure 目前可从源代码在所有可以运行 Go 的平台上获取,并且需要至少 Go 1.24。使用以下命令安装:$ go install github.com/glojurelang/glojure/cmd/glj@latest 安装后,您可以使用 glj 命令启动 REPL(读取-求值-打印-循环):$ glj user=> (println "Hello, world!") 你好,世界! nil user=> 使用方法 Glojure 可以以两种方式使用:作为独立的命令行工具(glj)或嵌入到 Go 应用程序中。使用 glj 命令 glj 命令提供传统的 Clojure 开发体验: 显示帮助:$ glj --help # 或 glj -h 显示版本:$ glj --version glojure v0.3.0 启动 REPL(交互式会话):user=> *glojure-version* {:major 0, :minor 3, :incremental 0, :qualifier nil} $ glj user=> (+ 1 2 3) 6 user=> (println "Hello from Glojure!") 来自 Glojure 的问候! nil REPL 特性 交互式 REPL 包括: Vi 和 emacs 编辑模式——vi 是默认模式;可通过 ~/.inputrc 配置 多行编辑——不完整表达式将在下一行继续并自动缩进 Tab 补全——符号、命名空间和带有描述标签的别名 智能缩进——Tab 插入 2 个空格;退格键删除整个缩进级别 持久历史——在会话之间保存到 ~/.glj_history 括号粘贴——快速粘贴代码块 作业控制——Ctrl+Z 挂起,fg 干净地恢复 中断——Ctrl+C 取消输入或中断评估 评估表达式:$ glj -e '(println "Hello, World!")' 你好,世界! $ glj -e '(apply + (range 3 10))' 42 $ glj -e '(defn factorial [n] (if (<= n 1) 1 (* n (factorial (dec n))))) (factorial 5)' 120 运行 Clojure 脚本: ; ; hello.glj (println "你好," (first *command-line-args*)) $ glj hello.glj 世界 你好,世界 创建可执行程序: ; ; server.glj (ns example.server) (defn echo-handler [w r] (io.Copy w (.Body r)) nil) (net:http.Handle "/" (net:http.HandlerFunc echo-handler)) (println " 服务在 :8080 上启动... ") (net:http.ListenAndServe ":8080" nil) $ glj server.glj 服务在 :8080 上启动... 在 Go 应用程序中嵌入 Glojure 您也可以将 Glojure 作为脚本语言嵌入到 Go 应用程序中。这在您想要时很有用: 为您的 Go 应用程序添加可脚本化的配置 允许用户通过 Clojure 插件扩展您的应用程序 将 Go 的性能与 Clojure 的表现力相结合 控制执行环境(自定义 I/O、沙箱) 基本嵌入示例: package main import ("fmt" _ "github.com/glojurelang/glojure/pkg/glj" // 初始化 Glojure "github.com/glojurelang/glojure/pkg/runtime") func main() { // 评估 Clojure 代码 result := runtime.ReadEval(`(defn factorial [n] (if (<= n 1) 1 (* n (factorial (dec n))))) (factorial 5)`) fmt.Printf("5! = %v \n", result) // 5! = 120 } 从 Clojure 和 Go 反向调用: package main import ("fmt" "github.com/glojurelang/glojure/pkg/glj" "github.com/glojurelang/glojure/pkg/runtime") // 定义一个 Go 函数 func greet(name string) string { return fmt.Sprintf("Hello, %s from Go!", name) } func main() { // 将 Go 函数提供给 Clojure runtime.ReadEval(`(def greet-from-go nil)`) // 占位符 greetVar := glj.Var("user", "greet-from-go") greetVar.SetRoot(greet) // 从 Clojure 使用它 result := runtime.ReadEval(`(greet-from-go "Clojure")`) fmt.Println(result) // "Hello, Clojure from Go!" // 从 Go 调用 Clojure 函数 runtime.ReadEval(`(defn add [x y] (+ x y))`) addFn := glj.Var("user", "add") sum := addFn.Invoke(10, 32) fmt.Printf("Sum: %v \n", sum) // Sum: 42 } 访问您自己的 Go 包: 在嵌入 Glojure 时,您还可以使用下面访问其他 Go 包部分所描述的包映射方法来公开您自己的 Go 包或其他标准库包。这允许嵌入的 Clojure 代码访问您选择公开的任何 Go 包: import (_ "github.com/glojurelang/glojure/pkg/glj" _
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡