自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

PHP vs Go,為什么 Go 不支持命名參數(shù)調(diào)用函數(shù)?

開發(fā) 前端
“為什么 Go 不能像 PHP、Python 一樣,在調(diào)用函數(shù)時(shí),直接帶上參數(shù)名和值一起傳入。這樣就不用特意去看這個(gè)函數(shù)的形參的命名、類型等。明明 PHP8 都支持了?”

大家好,我是煎魚。

之前在《Go 語(yǔ)言設(shè)計(jì)哲學(xué)[1]》電子書中分享了《??為什么 Go 不支持函數(shù)重載和缺省參數(shù)???》的思考和原因。最近有一位從其他編程語(yǔ)言轉(zhuǎn)型 Go 的同學(xué)提出了如下靈魂拷問。

“為什么 Go 不能像 PHP、Python 一樣,在調(diào)用函數(shù)時(shí),直接帶上參數(shù)名和值一起傳入。這樣就不用特意去看這個(gè)函數(shù)的形參的命名、類型等。明明 PHP8 都支持了?”

今天針對(duì)命名參數(shù)這個(gè)特性展開思考,看看 Go 怎么回事。

命名參數(shù)

如果有了命名參數(shù)這個(gè)功能特性,在我們調(diào)用函數(shù)/方法時(shí),傳入函數(shù)的參數(shù)不需要固定位置,位置可以隨意調(diào)整,名字對(duì)就行。甚至有的工具會(huì)基于此,做自動(dòng)化的文檔等自描述的場(chǎng)景。

PHP8 的例子:

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

// 兩次調(diào)用的參數(shù)位置不一樣
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)
}

由于不支持,運(yùn)行編譯就會(huì)報(bào)錯(cuò):

./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) // 輸出結(jié)果:35
}

也就是按函數(shù)所聲明的參數(shù)位置傳入,才能運(yùn)行成功。

設(shè)計(jì)哲學(xué)

Go 語(yǔ)言在錯(cuò)誤處理、函數(shù)重載以及缺省參數(shù)等社區(qū)議題討論時(shí),總會(huì)祭出其的設(shè)計(jì)理念是:“顯式大于隱喻”,追求明確,顯式,要不就是 “l(fā)ess is more”。

每次看到只要不滿足這個(gè)理念的提案、討論,基本 Go 團(tuán)隊(duì)可以圍繞這個(gè)論據(jù)給出一堆理由后拒絕掉。

本文提到的帶命名參數(shù)傳入函數(shù),看起來非常顯式,很明確了。似乎很符合 Go 的設(shè)計(jì)哲學(xué)理念,感覺不應(yīng)該沒有才對(duì)?

社區(qū)思考

在 golang-nuts 郵件群組的多年討論中,涉及到以下幾類論據(jù)作為支撐:

  • 這是一個(gè)語(yǔ)言設(shè)計(jì)和可讀性問題,“命名參數(shù)” 和 “缺省參數(shù)” 基本是成配套出現(xiàn)在語(yǔ)言設(shè)計(jì)中,需要一并考量合適與否。會(huì)出現(xiàn)一加就相當(dāng)于要引入許多新語(yǔ)法特性了,能玩出騷操作。
  • 引入這類特性會(huì)給 Go 帶來新語(yǔ)法復(fù)雜度,如果函數(shù)參數(shù)名修改了,那是不是破壞兼容性?是不是調(diào)用方全都得改一遍?如果出現(xiàn)同名的參數(shù)名,誰(shuí)先誰(shuí)后?怎么覆蓋?過長(zhǎng)的話,函數(shù)調(diào)用會(huì)不會(huì)過于難接受?組合結(jié)構(gòu)體覆蓋方法時(shí),方法參數(shù)名需不需要保持一致?會(huì)產(chǎn)生一大堆新問題。
  • 引入后會(huì)產(chǎn)生大量的函數(shù)可選參數(shù)(命名參數(shù)+缺省參數(shù)),原本只需要知道函數(shù)形參是什么,結(jié)果引入后需要查看名字、缺省值以及對(duì)應(yīng)的缺省邏輯等,會(huì)加大程序員心智負(fù)擔(dān)。
  • 編譯器本身不需要關(guān)注這些信息,為這個(gè)特性加大編譯器的各項(xiàng)開銷是不必要的,沒有理由讓編譯器在編譯代碼中存儲(chǔ)函數(shù)的參數(shù)名稱(需要具體考究深意)。

我們?cè)谟懻撝幸灿刑岬剑@個(gè)特性可以借助 go:generate 的特性來實(shí)現(xiàn)類似的功能,有興趣的朋友可以看看 go-named-params[2] 這個(gè)開源庫(kù)。

顯然官方態(tài)度是,增加命名參數(shù)特性的弊大于利,貿(mào)然增加會(huì)影響到 Go 本身標(biāo)榜的優(yōu)勢(shì)(簡(jiǎn)潔)。認(rèn)為大可不必加,工具的問題需要讓工具自己解決。

總結(jié)

在這篇文章中,我們針對(duì)其他編程語(yǔ)言既有的 “命名參數(shù)” 特性進(jìn)行了分析和說明。顯然 Go 團(tuán)隊(duì)在討論中,認(rèn)為該項(xiàng)特性對(duì)于靜態(tài)語(yǔ)言,尤其對(duì)于 Go 團(tuán)隊(duì)來講,似乎好處太少,加了會(huì)影響自己的風(fēng)格(less is more),還可能會(huì)影響性能,真是大可不必。

各語(yǔ)言間的功能特性對(duì)比,是個(gè)老大難的問題。如果都一樣,那豈不是搞個(gè)大單體編程語(yǔ)言算了?這顯然是不現(xiàn)實(shí)的。

參考資料

[1]Go 語(yǔ)言設(shè)計(jì)哲學(xué): https://golang3.eddycjy.com/

[2]go-named-params: https://github.com/elliotchance/go-named-params

責(zé)任編輯:武曉燕 來源: 腦子進(jìn)煎魚了
相關(guān)推薦

2021-11-08 11:02:01

Go函數(shù)重載

2021-10-27 07:15:36

Go 循環(huán)引用

2021-12-09 10:51:47

Go繼承

2021-12-15 07:49:22

Go語(yǔ)言設(shè)計(jì)

2024-03-08 08:51:59

Gomain函數(shù)

2023-01-28 08:05:32

轉(zhuǎn)換Go泛型

2024-01-01 08:10:40

Go語(yǔ)言map

2024-01-05 08:45:35

Go語(yǔ)言map

2024-05-28 08:55:52

2024-03-12 09:13:28

Go語(yǔ)言main

2023-04-03 11:21:29

PythonGoRust

2020-07-22 08:01:41

Python開發(fā)運(yùn)算符

2020-10-09 06:48:19

Pythonswitch語(yǔ)句

2023-11-29 08:19:45

Go泛型缺陷

2021-02-01 13:53:53

StringlongJava

2009-03-12 08:42:38

AndroidWMMTK

2021-08-02 09:31:20

Python工具代碼

2021-06-11 00:03:31

鴻蒙智能手機(jī)

2021-07-13 08:09:34

微博推特評(píng)論

2022-01-10 23:54:56

GoMap并發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)