PHP vs Go,为什么 Go 函数不支持命名参数?

之前在《Go 语言设计哲学[1]》电子书中分享了《为什么 Go 不支持函数重载和缺省参数?》的思考和原因。最近有一位从其他编程语言转型 Go 的同学提出了如下灵魂拷问。

“为什么 Go 不能像 PHP、Python 一样,在调用函数时,直接带上参数名和值一起传入。这样就不用特意去看这个函数的形参的命名、类型等。明明 PHP8 都支持了?”

今天针对命名参数这个特性展开思考,看看 Go 怎么回事。

命名参数

如果有了命名参数这个功能特性,在我们调用函数/方法时,传入函数的参数不需要固定位置,位置可以随意调整,名字对就行。甚至有的工具会基于此,做自动化的文档等自描述的场景。

PHP8 的例子:

function hello(string $name, int $age) {
    echo $name, $age;
}

// 两次调用的参数位置不一样
hello(name:'煎鱼', age:18);
hello(age:18, name:'煎鱼');

理想中 Go 的例子:

package main

func sum(a int, b int) int {
 return a + b
}

func main() {
 resp := sum(a=7, b=28)
 println(resp)
}

由于不支持,运行编译就会报错:

./prog.go:8:15: syntax error: unexpected = in argument list; possibly missing comma or )

Go 必须是如下代码:

func sum(a int, b int) int {
 return a + b
}

func main() {
 resp := sum(7, 28)
 println(resp)    // 输出结果:35
}

也就是按函数所声明的参数位置传入,才能运行成功。

设计哲学

Go 语言在错误处理、函数重载以及缺省参数等社区议题讨论时,总会祭出其的设计理念是:“显式大于隐喻”,追求明确,显式,要不就是 “less is more”。

每次看到只要不满足这个理念的提案、讨论,基本 Go 团队可以围绕这个论据给出一堆理由后拒绝掉。

本文提到的带命名参数传入函数,看起来非常显式,很明确了。似乎很符合 Go 的设计哲学理念,感觉不应该没有才对?

社区思考

在 golang-nuts 邮件群组的多年讨论中,涉及到以下几类论据作为支撑:

  • 这是一个语言设计和可读性问题,“命名参数” 和 “缺省参数” 基本是成配套出现在语言设计中,需要一并考量合适与否。会出现一加就相当于要引入许多新语法特性了,能玩出骚操作。

  • 引入这类特性会给 Go 带来新语法复杂度,如果函数参数名修改了,那是不是破坏兼容性?是不是调用方全都得改一遍?如果出现同名的参数名,谁先谁后?怎么覆盖?过长的话,函数调用会不会过于难接受?组合结构体覆盖方法时,方法参数名需不需要保持一致?会产生一大堆新问题。

  • 引入后会产生大量的函数可选参数(命名参数+缺省参数),原本只需要知道函数形参是什么,结果引入后需要查看名字、缺省值以及对应的缺省逻辑等,会加大程序员心智负担。

  • 编译器本身不需要关注这些信息,为这个特性加大编译器的各项开销是不必要的,没有理由让编译器在编译代码中存储函数的参数名称(需要具体考究深意)。

我们在讨论中也有提到,这个特性可以借助 go:generate 的特性来实现类似的功能,有兴趣的朋友可以看看 go-named-params[2] 这个开源库。

显然官方态度是,增加命名参数特性的弊大于利,贸然增加会影响到 Go 本身标榜的优势(简洁)。认为大可不必加,工具的问题需要让工具自己解决。

总结

在这篇文章中,我们针对其他编程语言既有的 “命名参数” 特性进行了分析和说明。显然 Go 团队在讨论中,认为该项特性对于静态语言,尤其对于 Go 团队来讲,似乎好处太少,加了会影响自己的风格(less is more),还可能会影响性能,真是大可不必。

各语言间的功能特性对比,是个老大难的问题。如果都一样,那岂不是搞个大单体编程语言算了?这显然是不现实的。

参考资料

[1]

Go 语言设计哲学: https://golang3.eddycjy.com/

[2]

go-named-params: https://github.com/elliotchance/go-named-params

关注煎鱼微信公众号,

一手消息和知识每周更新👇

9a1b41c924a8416b12cba6e0b96c937c.png

- END -

扫码关注公众号「网管叨bi叨」

给网管个星标,第一时间吸我的知识 👆

网管整理了一本《Go 开发参考书》收集了70多条开发实践。去公众号回复【gocookbook】领取!还有一本《k8s 入门实践》讲解了常用软件在K8s上的部署过程,公众号回复【k8s】即可领取!

觉得有用就点个在看  👇👇👇

‍‍‍‍‍

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值