Gleam的酷炫之处

Lobsters Hottest 工具

摘要

作者分享了学习Gleam编程语言的个人笔记,重点介绍了@deprecated属性、todo构造、泛型和case表达式等特性,并与其他语言进行了比较。

<p><a href="https://lobste.rs/s/lzgbrv/cool_things_gleam">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/08/22 09:05

# Gleam 的酷炫特性 来源:https://a.baez.link/3mtdbbp2dmc27 好吧,我越来越喜欢 Gleam 了。我接触这门语言时间还不长(顺便一提,上周才开始——https://bsky.app/profile/a.baez.link/post/3msrduve57k23)。但即便如此,我真心喜欢它的简洁性。以下是学习这门语言至今的一些快速笔记。 ### `@deprecated` 属性 (https://a.baez.link/3mtdbbp2dmc27#the-deprecated-attribute) 很容易忽视它的价值。但如果你写过太多 GraphQL (https://graphql.org/),你就会了解 `@deprecated` 装饰器 (https://spec.graphql.org/September2025/#sec-Field-Deprecation)。在 Gleam 中,`@deprecated` 的作用方式完全相同。你只需添加一个函数属性来告诉编译器应该去哪里寻找新方法: ```gleam @deprecated("Use new_way. It's better") fn old_way(x: String) -> String { x } fn new_way(x: nice) -> nice { x } ``` 简单且极其有效。它有助于指明在何处查找库函数的新版本。一旦你有了这样的注解系统,开发会变得稍微容易一些。当你没有它时,你会很快想念它! ### Todo (https://a.baez.link/3mtdbbp2dmc27#todo) 你是否曾在代码的某个地方写过 todo?我的意思是……确实有专门的 todo 检查工具 (https://golangci-lint.run/docs/linters/configuration/#godox)。而在 Gleam 中,`todo` 是一个内置构造。你可以这样标识: ```gleam fn something() -> String { todo as "maybe, should do something" } ``` 这样不仅可以标识有待办事项,还能提供关于 todo 实际需要做什么的详细信息。我数不清写过多少次这种小 todo 注释了。所以可以说,我对内置这个选项感到很满意。 ### 泛型 (https://a.baez.link/3mtdbbp2dmc27#generics) 无论你走到哪里,都会发现关于如何正确实现泛型的论文连篇累牍。泛型,也被称为参数多态 (https://en.wikipedia.org/wiki/Parametric_polymorphism)。例如,在 Go 中,我们不得不等到 1.18 版本 (https://go.dev/doc/go1.18#generics) 才能使用: ```go type Num interface { int | string } func Mistakes[T Num](val T) T { return val } ``` Go 的方式并不差。特别是当你想起在 C++ (https://dear-computer.twodee.org/polymorphism-revisited/generics-in-cpp.html) 中如何实现,或者在 Go 中你仍然需要与他人争论是使用泛型还是接口时……但在 Gleam 中: ```gleam fn Mistakes(val: woah) -> woah { val } ``` Gleam 将泛型类型作为函数类型注解的一部分来处理。一些能力在更严格的构造中会丧失,例如受限泛型。但好处在于简洁性和可读性。 ### 万物皆 `case` (https://a.baez.link/3mtdbbp2dmc27#case-everything) 你看,在 BEAM 语言(如 Elixir、Erlang 或 Gleam)中,你必须使用模式匹配。这是这些语言的超能力。也许是最大的超能力。 举个能在 Beam 语言之外翻译的简单例子,比如检查一个整数是否为零。在 Elixir 中,你可以用函数实现这种魔力: ```elixir def zero?(0), do: true def zero?(maybe) when is_integer(maybe), do: false ``` 这在 Go 中可以翻译成类似这样的代码: ```go func zero(maybe int) bool { switch maybe { case 0: return true default: return false } } ``` 我个人非常喜欢 Elixir 的魔力。感觉像炼金术。但另一方面……它确实有点像。要让那两行代码工作,需要宏 (https://elixir.hexdocs.pm/macros.html)、原子 (https://elixir.hexdocs.pm/Atom.html)、守卫 (https://elixir.hexdocs.pm/main/patterns-and-guards.html#guards) 构造、函数类型检查 (https://elixir.hexdocs.pm/Kernel.html#is_integer/1)、重载和模式匹配 (https://elixir.hexdocs.pm/pattern-matching.html)。 而在 Gleam 中,这门语言采取了用一种简单方式仔细做事的方法。这意味着 `case` (https://tour.gleam.run/flow-control/case-expression/) 表达式就是你的一切: ```gleam fn zero(maybe Int) -> Bool { case maybe { 0 -> True _ -> False } } ``` 虽然看起来与 Go 的方式相似,而与 Elixir 的方式差异较大,但 Gleam 是在检查每个操作响应应该是什么。因此,对于模式匹配语言来说更困难的构造,比如列表解构,仍然是直接的 case 匹配: ```gleam // 返回第一个至少有2个元素的列表 fn first_with_many(lists: List(List(t))) -> List(t) { case lists { [] -> [] // 注意模式别名! [[_, _, ..] as first, ..] -> first [_, ..rest] -> first_with_many(rest) } } ``` ### 没有异常! (https://a.baez.link/3mtdbbp2dmc27#no-exceptions) 对于许多语言来说,异常只是处理错误的一种方式。Python 中的异常处理几乎是必须的,不可避免。 然而在 Gleam 中,类型系统就是为无异常而构建的。Elm (https://elm-lang.org/) 以这种设计而闻名。要在这些语言之外做这样的事情,你必须对编写代码的方式非常严格和有条理。但在 Gleam 中,这只是语言工作方式的一部分。 ```gleam let x: Option(Int) = None // 如果是 None,则默认为 -1 let y = option.unwrap(x, -1) ``` 你要么得到 `unwrap` 的结果,要么得到你定义的默认值。搞定。 ### 没有 Null (https://a.baez.link/3mtdbbp2dmc27#no-nulls) 这一点肯定源自 Gleam 中的 Rust 部分。这门语言没有 null/nil 值。是的。技术上有一个 `Nil` 类型,但它只能被设置为它自身。你不能让一个 `Int` 成为 `Nil` 值。但是,确实存在某物缺失的概念。你使用 `Option` (https://gleam-stdlib.hexdocs.pm/gleam/option.html#Option) 来处理这个。 而如果你想了解错误,你使用 `Result` (https://gleam-stdlib.hexdocs.pm/gleam/result)。 ```gleam let err = Error("yes, things went the wrong way") ``` --- 就是这样!这门语言还有其他巧妙的技巧,但正是这种简洁性,真正让我信服了它的能力。

相似文章

面向Python程序员的Gleam

Lobsters Hottest

一个免费的在线教程,向Python程序员教授函数式编程语言Gleam,涵盖从基础知识到高级主题,如键值存储、Web API和流处理。

Gleam and the value of small

Lobsters Hottest

Gleam 是一门刻意保持简洁的函数式编程语言,通过精简关键字、避免重复来提升可读性和开发体验,其设计理念是“少即是多”。

Gleam v1.17.0

Hacker News Top

Gleam v1.17.0 引入了 `gleam export escript` 命令以创建单文件 BEAM 程序,在语言服务器中高亮引用,以及常量 `todo` 表达式。此外,首届 Gleam Gathering 大会的视频也已发布。