新聞中心
大家好,我是煎魚。

之前在《Go 語言設(shè)計哲學(xué)[1]》電子書中分享了《??為什么 Go 不支持函數(shù)重載和缺省參數(shù)???》的思考和原因。最近有一位從其他編程語言轉(zhuǎn)型 Go 的同學(xué)提出了如下靈魂拷問。
“為什么 Go 不能像 PHP、Python 一樣,在調(diào)用函數(shù)時,直接帶上參數(shù)名和值一起傳入。這樣就不用特意去看這個函數(shù)的形參的命名、類型等。明明 PHP8 都支持了?”
今天針對命名參數(shù)這個特性展開思考,看看 Go 怎么回事。
命名參數(shù)
如果有了命名參數(shù)這個功能特性,在我們調(diào)用函數(shù)/方法時,傳入函數(shù)的參數(shù)不需要固定位置,位置可以隨意調(diào)整,名字對就行。甚至有的工具會基于此,做自動化的文檔等自描述的場景。
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)
}
由于不支持,運行編譯就會報錯:
./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ù)位置傳入,才能運行成功。
設(shè)計哲學(xué)
Go 語言在錯誤處理、函數(shù)重載以及缺省參數(shù)等社區(qū)議題討論時,總會祭出其的設(shè)計理念是:“顯式大于隱喻”,追求明確,顯式,要不就是 “l(fā)ess is more”。
每次看到只要不滿足這個理念的提案、討論,基本 Go 團隊可以圍繞這個論據(jù)給出一堆理由后拒絕掉。
本文提到的帶命名參數(shù)傳入函數(shù),看起來非常顯式,很明確了。似乎很符合 Go 的設(shè)計哲學(xué)理念,感覺不應(yīng)該沒有才對?
社區(qū)思考
在 golang-nuts 郵件群組的多年討論中,涉及到以下幾類論據(jù)作為支撐:
- 這是一個語言設(shè)計和可讀性問題,“命名參數(shù)” 和 “缺省參數(shù)” 基本是成配套出現(xiàn)在語言設(shè)計中,需要一并考量合適與否。會出現(xiàn)一加就相當(dāng)于要引入許多新語法特性了,能玩出騷操作。
- 引入這類特性會給 Go 帶來新語法復(fù)雜度,如果函數(shù)參數(shù)名修改了,那是不是破壞兼容性?是不是調(diào)用方全都得改一遍?如果出現(xiàn)同名的參數(shù)名,誰先誰后?怎么覆蓋?過長的話,函數(shù)調(diào)用會不會過于難接受?組合結(jié)構(gòu)體覆蓋方法時,方法參數(shù)名需不需要保持一致?會產(chǎn)生一大堆新問題。
- 引入后會產(chǎn)生大量的函數(shù)可選參數(shù)(命名參數(shù)+缺省參數(shù)),原本只需要知道函數(shù)形參是什么,結(jié)果引入后需要查看名字、缺省值以及對應(yīng)的缺省邏輯等,會加大程序員心智負擔(dān)。
- 編譯器本身不需要關(guān)注這些信息,為這個特性加大編譯器的各項開銷是不必要的,沒有理由讓編譯器在編譯代碼中存儲函數(shù)的參數(shù)名稱(需要具體考究深意)。
我們在討論中也有提到,這個特性可以借助 go:generate 的特性來實現(xiàn)類似的功能,有興趣的朋友可以看看 go-named-params[2] 這個開源庫。
顯然官方態(tài)度是,增加命名參數(shù)特性的弊大于利,貿(mào)然增加會影響到 Go 本身標(biāo)榜的優(yōu)勢(簡潔)。認為大可不必加,工具的問題需要讓工具自己解決。
總結(jié)
在這篇文章中,我們針對其他編程語言既有的 “命名參數(shù)” 特性進行了分析和說明。顯然 Go 團隊在討論中,認為該項特性對于靜態(tài)語言,尤其對于 Go 團隊來講,似乎好處太少,加了會影響自己的風(fēng)格(less is more),還可能會影響性能,真是大可不必。
各語言間的功能特性對比,是個老大難的問題。如果都一樣,那豈不是搞個大單體編程語言算了?這顯然是不現(xiàn)實的。
參考資料
[1]Go 語言設(shè)計哲學(xué): https://golang3.eddycjy.com/
[2]go-named-params: https://github.com/elliotchance/go-named-params
當(dāng)前題目:PHPvsGo,為什么Go不支持命名參數(shù)調(diào)用函數(shù)?
分享鏈接:http://m.5511xx.com/article/dhccpjh.html


咨詢
建站咨詢
