Borgo 是一种静态类型的语言,可以编译成 Go 语言,并在努力与现有的 Go 生态系统实现互操作。Borgo 语言为 Go 语言添加了代数数据类型、模式匹配、Option 和 Result 类型,以及很多受 Rust 启发的语法。Borgo 的编译器本身是用 Rust 实现的。
Borgo 的主要贡献者对 Borgo 的主要特征进行了解释:
我想要一种编写应用程序的语言,它比 Go 更具表现力,但比 Rust 更简单。
Go 虽然简单明了,但我经常希望它能提供更多的类型安全性。Rust 非常好用(至少对于单线程代码来说是这样),但它过于宽泛和复杂,有时甚至让人感到痛苦。
Borgo 是一种新的语言,可以转换成 Go 语言。它与现有的 Go 软件包完全兼容。
Borgo 语法类似于 Rust,带有可选的分号。
Go 因其简单、高效和对并发性的处理而迅速受到许多开发人员的欢迎。Go 的设计也有利于快速编译。截至 2024 年 5 月,该语言在 TIOBE 指数中排名第 8 位。然而,开发人员经常指责 Go 在设计上是弱类型语言的缺点。Ian Lance Taylor 是 Go 的主要贡献者,他将弱类型视为一种特性而非缺陷:
Go 故意使用弱类型系统,并且有很多可以用其他语言表达但不能用 GO 表达的限制。Go 通常鼓励通过编写代码来进行编程,而不是通过编写类型来进行编程。
然而,许多经验丰富的 Go 开发人员已经表示了对丰富类型系统的兴趣。例如,一位 Reddit 用户提到:
错误作为值是好的,但是缺少求和(sum)类型却会造成伤害。
缺少返回错误的语法糖会导致样板代码。
缺乏适当的类型定义意味着我不能随心所欲地使用类型安全性。
Borgo 语言的语法似乎在很大程度上受到了 Rust 的启发,在努力保持与现有 Go 库兼容性的同时,Borgo 为 Go 添加了关键的语言特性。下面的代码演示了 Borgo 的代数数据类型和模式匹配:
use fmt
enum NetworkState<T> {
Loading,
Failed(int),
Success(T),
}
struct Response {
title: string,
duration: int,
}
fn main() {
let res = Response {
title: "Hello world",
duration: 0,
}
let state = NetworkState.Success(res)
let msg = match state {
NetworkState.Loading => "still loading",
NetworkState.Failed(code) => fmt.Sprintf("Got error code: %d", code),
NetworkState.Success(res) => res.title,
}
fmt.Println(msg)
}
复制代码
下面的代码示例演示了 Borgo 受 Rust 启发的 Result
和 Option
类型( strconv.Atoi
返回 Option<int>
类型,Reader.ReadString
返回 Result<string, error>
):
use bufio
use fmt
use math.rand
use os
use strconv
use strings
use time
fn main() {
let reader = bufio.NewReader(os.Stdin)
let secret = rand.Intn(100) + 1
loop {
fmt.Println("Please input your guess.")
let text = reader.ReadString('\n').Unwrap()
let text = strings.TrimSpace(text)
let guess = match strconv.Atoi(text) {
Ok(n) => n,
Err(_) => continue,
}
fmt.Println("You guessed: ", guess)
if guess < secret {
fmt.Println("Too small!")
} else if guess > secret {
fmt.Println("Too big!")
} else {
fmt.Println("Correct!")
break
}
}
}
复制代码
Borgo 还允许使用 ?
操作符:
use fmt
use io
use os
fn copyFile(src: string, dst: string) -> Result<(), error> {
let stat = os.Stat(src)?
if !stat.Mode().IsRegular() {
return Err(fmt.Errorf("%s is not a regular file", src))
}
let source = os.Open(src)?
defer source.Close()
let destination = os.Create(dst)?
defer destination.Close()
// 忽略复制的字节数
let _ = io.Copy(destination, source)?
Ok(())
}
复制代码
由于 Borgo 的编译器是用 Rust 编写的,开发人员需要用 cargo
来编译 Borgo 的源文件:
编译器将生成.go 文件,这些文件可以使用常用的 Go 工具链来运行:
# 如果需要,生成一个 go.mod 文件
# $ go mod init foo
$ go run .
复制代码
最近,来自 Reddit 上的开发者的反应总体上是积极的,其中一位开发者 表示:
这几乎解决了我在工作中编写 Go 代码时最不喜欢的事情,我希望——至少——这些压倒性的积极回复(按照 HN 的标准——甚至考虑到典型的 Rust 偏见!)能够激励 Go 的维护人员考虑 / 优先考虑其中的一些特性。
Borgo 语言特性的完整列表可以在在线文档和 Borgo 的游乐场中找到。
原文链接:
https://www.infoq.com/news/2024/05/borgo-adds-types-to-go/
评论