2025年4月21日 星期一 乙巳(蛇)年 正月廿二 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Go语言

为啥 Go 的变量类型要放在变量名后面?

时间:12-14来源:作者:点击数:5

早上看一篇博客 Cloud-Native Java vs Golang(link:https://medium.com/swlh/cloud-native-java-vs-golang-2a72c0531b05),然后上它的 github仓库,顺便溜了要一眼下面的这段代码:

  • package org.acme
  • import io.vertx.core.json.JsonArray
  • import io.vertx.core.json.JsonObject
  • import io.vertx.mutiny.mysqlclient.MySQLPool
  • import io.vertx.mutiny.sqlclient.Row
  • import io.vertx.mutiny.sqlclient.RowSet
  • import java.util.concurrent.CompletionStage
  • import javax.inject.Inject
  • import javax.ws.rs.GET
  • import javax.ws.rs.Path
  • import javax.ws.rs.Produces
  • import javax.ws.rs.core.MediaType
  • @Path("/fruits")
  • class FruitResource {
  • @field:Inject
  • lateinit var client: MySQLPool
  • @GET
  • @Produces(MediaType.APPLICATION_JSON)
  • fun listFruits(): CompletionStage<JsonArray> {
  • return client.query("SELECT * FROM fruits").execute()
  • .map { rows: RowSet<Row> ->
  • rows.fold(JsonArray()) { array, row ->
  • array.add(JsonObject()
  • .put("id", row.getLong("id"))
  • .put("name", row.getString("name")))
  • }
  • }.subscribeAsCompletionStage()
  • }
  • }

我发现:

  1. vertx 也提供了 JSON 的支持 io.vertx.core.json.JsonArray,你看vertx也有JSON实现呢,你需要的时候,可以参考一下哦,毕竟 vertx 还是挺有名的嘛。因为它前期就搞 JSON 支持切换 fastjson 和 gson 的实现(fastjson 频繁暴露安全问题,参见 fastjson 到底做错了什么?为什么会被频繁爆出漏洞?),准备能随时在遇到安全问题时,切换实现。
  2. 然后一看这个是 kotlin 语法,竟然也是类型后置(变量类型放在变量名称后面),跟 go 语言一样。我在想,是不是比较新的语言,包括 rust,都是这么设计的啊。就像 StackOverflow 中说的这样 几乎所有现代编程语言(Go、 Rust、 Kotlin、 Swift、 Scala、 Nim,甚至 Python 最后版本)中,类型总是在变量声明之后出现(link:https://softwareengineering.stackexchange.com/a/316243)

然后我就想起,这个设计,并不单单是因为 style 的问题,而是有真实好处的。然后我就百度一下 why golang put type declaration afterwards,得到以下几条答案:

理论习惯

在形式语言理论和类型理论中,它几乎总是被写成 var: type。例如,在形式化λ演算,你会看到包含如下陈述的证明:

  • x : A y : B
  • -------------
  • \x.y : A->B

我不认为这真的很重要,但我认为有两个理由: 一个是 x: a 被读作 x 是 a 型的 ,另一个是一个类型就像一个集合(例如 int 是整数的集合) ,例如 x ε a。

这些东西中的一些比你所想的现代语言还要早。

避免混淆

例如C语言中的 int* a, b;,只是声明了 a 是指针,而 b 并不是。或者 Go's Declaration Syntax 中提到的函数指针的声明的例子。

  • int (*fp)(int a, int b);

上述声明了一个函数指针 fp,指向两个整型入参和一个整型出参的函数类型。这个还比较容易理解。好像,如果我们把第一个参数也换成函数指针,就要这么写了:

  • int (*fp)(int (*ff)(int x, int y), int b);

开始看起来费劲了吧。

换成 go 版本的看看:

  • f func(func(int,int) int, int) int

是不是容易看懂很多(习惯了类型后置的写法之后)。

特别是看到C语言的这种,int *(*func())();,肯定是要抓瞎了,大喊:「苍天啊,救救我吧!」然后GO说:「虽然我不是苍天,但是我能救你,欢迎使用GO!」

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐