偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Go 為什么不支持從 main 包中導(dǎo)入函數(shù)?

開(kāi)發(fā) 前端
在本次對(duì) Go 工具限制從 main 包中導(dǎo)入相關(guān)函數(shù)的緣由,我們做了詳盡的了解和分析。雖然 Go 官方這樣的方式可以一刀切的解決復(fù)雜度和安全性的問(wèn)題。

大家好,我是煎魚(yú)。

作為一個(gè)維護(hù)過(guò)許多有一定歷史沉淀的 Go 項(xiàng)目的人,在歷史債務(wù)下和奇葩需求下,會(huì)遇到一些迫于業(yè)務(wù)需求的技術(shù)訴求。

訴求上是希望引用多項(xiàng)目,會(huì)出現(xiàn)從 main 包(package)中導(dǎo)入相關(guān)函數(shù)的這種使用訴求。為了將多 Go 工程合并到一個(gè)大單體中使用。

問(wèn)題案例

具體的使用案例如下。

我們有一個(gè) Go 應(yīng)用,目錄結(jié)構(gòu)如下:

demo1
├── go.mod
├── main.go
└── x
    └── main.go

demo1/x/main.go 文件內(nèi)代碼如下:

package main

import (
 "fmt"
)

func main() {
 Main()
}

func Main() {
 fmt.Println("煎魚(yú)進(jìn)水了?")
}

demo1/main.go 文件內(nèi)代碼如下:

package main

import (
 "fmt"

 xmain "example.com/greet/x"  // 也就是本應(yīng)用,上面的 x
)

func main() {
 fmt.Println("腦子進(jìn)煎魚(yú)了!")
 xmain.Main()
}

簡(jiǎn)單來(lái)講,就是 demo1 這個(gè) Go 項(xiàng)目,擁有兩個(gè) main 包。根目錄下的 main.go 文件內(nèi)引用了 x/main.go 內(nèi)的 Main 方法。

運(yùn)行該程序,看看運(yùn)行結(jié)果:

$ go run main.go
main.go:6:2: import "example.com/greet/x" is a program, not an importable package

會(huì)直接報(bào)錯(cuò),提示 x 包下是一個(gè)程序,而不是一個(gè)可導(dǎo)入的包。

為什么不支持導(dǎo)入 main 包

這個(gè)問(wèn)題稍微可以收斂一下,關(guān)鍵內(nèi)容是:為什么不支持導(dǎo)入 main 包內(nèi)的函數(shù)?明明 main 包也是一個(gè) package,其個(gè)別函數(shù)也是大寫(xiě)開(kāi)頭,是允許對(duì)外導(dǎo)出的。

我首先翻閱了一下 Go 語(yǔ)言規(guī)范(spec),確實(shí)沒(méi)有非常明確禁止該項(xiàng)行為。但又確實(shí)在我們?nèi)粘J褂煤途幾g運(yùn)行時(shí),會(huì)被拒絕運(yùn)行。提示前面的錯(cuò)誤。

隨后又查看了具體的代碼提交和 CL,實(shí)際上在 13 年前。現(xiàn)任 Go 核心團(tuán)度負(fù)責(zé)人 @rsc 是提交過(guò)相應(yīng) main 包支持的。

如下 CL 所示:

圖片圖片

2011 年(13 年前)的 CL 移除了原本語(yǔ)言規(guī)范中定義的 “程序中的其他包都不能命名為 main” 的要求,也就是可以滿(mǎn)足前文問(wèn)題和背景中提到的使用訴求。

看到這里有的同學(xué)就疑惑了。怎么 13 年后的現(xiàn)在,2024 年。又不行了呢?而且感覺(jué)是不行好久了。

因?yàn)樵?2015 年時(shí),現(xiàn)任 Go 核心團(tuán)隊(duì)成員 @ianlancetaylor,又又又改了,增加了非常明確的判斷,直接限制了。

如下代碼變更:

圖片圖片

比較有趣的是,@rsc 和 @ianlancetaylor 的變更都是針對(duì)同一個(gè) issues #4210:《cmd/go: go build does not reject importing commands》。

怎么后面又變了呢?@ianlancetaylor 給出的明確答復(fù)和定義:

圖片圖片

CL 4126053(原先 @rsc 提交的那次)是對(duì)描述語(yǔ)言規(guī)范的修改。該語(yǔ)言允許導(dǎo)入名為 main 的包。例如:在為使用 main 包的命令中的函數(shù)編寫(xiě)單元測(cè)試時(shí),就可以使用它。

但這里的問(wèn)題是關(guān)于 Go 工具,而不是語(yǔ)言。問(wèn)題是 go 工具是否應(yīng)該允許軟件包導(dǎo)入定義命令的包。普遍的共識(shí)是不應(yīng)該。

所提及的 Go 工具,覆蓋的范圍是:cmd/go。包含了 go build 等相關(guān)命令。因此是在受限制范圍的。

經(jīng)過(guò)如此切分場(chǎng)景,就能知道為什么語(yǔ)言規(guī)范上沒(méi)有明確禁止。但 Go 工具上又明確拒絕了。因?yàn)槠鋵?duì)應(yīng)覆蓋了不同的使用場(chǎng)景。

不支持的原因,結(jié)合討論來(lái)看。

普遍認(rèn)為支持 main 包的導(dǎo)入,會(huì)造成更大的復(fù)雜度和不安全性。

像是在 main 函數(shù)在編寫(xiě)時(shí),通常會(huì)假定自己擁有完全的控制權(quán),因此多個(gè) main 包內(nèi)的函數(shù)引入,可能會(huì)造成在 init 函數(shù)的初始化順序、全局變量的注冊(cè)等,都會(huì)產(chǎn)生程序上的沖突。

總結(jié)

在本次對(duì) Go 工具限制從 main 包中導(dǎo)入相關(guān)函數(shù)的緣由,我們做了詳盡的了解和分析。雖然 Go 官方這樣的方式可以一刀切的解決復(fù)雜度和安全性的問(wèn)題。

但有歷史沉淀、債務(wù)的情況下,對(duì)于需要維護(hù)多個(gè) Go 工程項(xiàng)目,要交付不同種類(lèi)的可組合項(xiàng)目的程序員來(lái)說(shuō)。相當(dāng)于磨滅了一條道路。還是比較尷尬的。

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

2024-03-12 09:13:28

Go語(yǔ)言main

2021-10-27 07:15:36

Go 循環(huán)引用

2021-11-08 11:02:01

Go函數(shù)重載

2023-02-26 23:36:08

PHPGo函數(shù)

2021-12-09 10:51:47

Go類(lèi)繼承

2021-12-15 07:49:22

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

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

2020-10-09 06:48:19

Pythonswitch語(yǔ)句

2020-07-22 08:01:41

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

2021-02-01 13:53:53

StringlongJava

2009-03-12 08:42:38

AndroidWMMTK

2021-06-11 00:03:31

鴻蒙智能手機(jī)

2021-08-02 09:31:20

Python工具代碼

2021-07-13 08:09:34

微博推特評(píng)論

2025-06-26 02:22:00

GoProtobuf標(biāo)簽

2023-04-03 11:21:29

PythonGoRust

2009-03-11 17:32:22

聯(lián)發(fā)科WMAndroid
點(diǎn)贊
收藏

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