色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

go語言底層對于命令行參數的解析

冬至子 ? 來源:我的小碗湯 ? 作者:小碗湯 ? 2022-10-11 10:50 ? 次閱讀

前段時間有群友在群里問一個go語言的問題:

就是有一個main.go的main函數里調用了另一個demo.go里的hello()函數。其中main.go和hello.go同屬于main包。但是在main.go的目錄下執行go run main.go卻報hello函數沒有定義的錯:

pYYBAGNE2XiAbE_6AABJdSb2xQ0407.png

代碼結構如下:

**gopath ---- src**

          **----gohello** 

                **----hello.go** 

                    **----main.go**

main.go如下:

package main

import "fmt"

func main() {

 fmt.Println("my name is main")

 hello()
}

hello.go如下:

package main

import "fmt"

func hello() {
 fmt.Println("my name is hello")
}

當時我看了以為是他GOPATH配置的有問題,然后自己也按照這樣試了一下,報同樣的錯,在網上查了,也有兩篇文章是關于這個錯的,也提供了解決方法,即用go run main.go hello.go,試了確實是可以的。

poYBAGNE2YqAUSTjAAA_Q8R_NUQ625.png

雖然是個很簡單的問題,但是也涉及到了go語言底層對于命令行參數的解析。那就來分析一下語言底層的實現吧,看一下底層做了什么,為什么報這個錯?

分析:

以下使用到的Go SDK版本為1.8.3

該版本中go支持的基本命令有以下16個:

build       compile packages and dependencies
clean       remove object files
doc         show documentation for package or symbol
env         print Go environment information
bug         start a bug report
fix         run go tool fix on packages
fmt         run gofmt on package sources
generate    generate Go files by processing source
get         download and install packages and dependencies
install     compile and install packages and dependencies
list        list packages
run         compile and run Go program
test        test packages
tool        run specified go tool
version     print Go version
vet         run go tool vet on packages

在Go SDK的src/cmd/go包下有main.go文件中,Command類型的commands數組對該16個命令提供了支持:

poYBAGNE2aGAGmHEAADVufp8n54966.png

我們首先知道go語言的初始化流程如下:

pYYBAGNE2bWAP7QzAABkuYqe9Uw995.png

在執行main.go中的主函數main之前,對import進來的包按順序初始化,最后初始化main.go中的類型和變量,當初始化到commands數組時,由于cmdRun定義在于main.go同包下的run.go中,那么就先去初始化run.go中的變量和init方法,如下代碼,先把cmdRun初始化為Command類型,然后執行init()函數。

var cmdRun = &Command{
 UsageLine: "run [build flags] [-exec xprog] gofiles... [arguments...]",
 Short:     "compile and run Go program",
 Long: `
Run compiles and runs the main package comprising the named Go source files.
A Go source file is defined to be a file ending in a literal ".go" suffix.

By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
If the -exec flag is given, 'go run' invokes the binary using xprog:
 'xprog a.out arguments...'.
If the -exec flag is not given, GOOS or GOARCH is different from the system
default, and a program named go_$GOOS_$GOARCH_exec can be found
on the current search path, 'go run' invokes the binary using that program,
for example 'go_nacl_386_exec a.out arguments...'. This allows execution of
cross-compiled programs when a simulator or other execution method is
available.

For more about build flags, see 'go help build'.

See also: go build.
 `,
}

func init() {
 cmdRun.Run = runRun // break init loop

 addBuildFlags(cmdRun)
 cmdRun.Flag.Var((*stringsFlag)(&execCmd), "exec", "")
}

init()中,將runRun(其實類型是一個方法,用于處理run后的參數)賦值給cmdRu.run,addBuildFlags(cmdRun)主要是給run后面增加命令行參數(如:-x是打印其執行過程中用到的所有命令,同時執行它們)。其他15個命令和cmdRun類似,各有各的run實現。

下來主要看main.go中main的這塊代碼:

for _, cmd := range commands {
   if cmd.Name() == args[0] && cmd.Runnable() {
     cmd.Flag.Usage = func() { cmd.Usage() }
     if cmd.CustomFlags {
       args = args[1:]
     } else {
       cmd.Flag.Parse(args[1:])
       args = cmd.Flag.Args()
     }
     cmd.Run(cmd, args)
     exit()
     return
   }
 }

這塊代碼遍歷commands數組,當遍歷到cmdRun時,cmd.Name()其實就是拿到cmdRun.UsageLine的第一個單詞run

bVeVF


就會進入if分支,由于cmd.CustomFlags沒有初始化故為false,走else分支,然后開始解析args命令行參數,args[1:]即取run后的所有參數。然后去執行cmd.Run(cmd, args),對于cmdRun來說,這里執行的就是run.go中init()的第一行賦值cmdRun.run(上面說了,這是一個函數,不同命令實現方式不同),即去執行run.go中的runRun函數,該函數主要是將命令行參數當文件去處理,如果是_test為后綴的,即測試文件,直接報錯。如果是目錄也直接報錯(而且go run后面只能包含一個含main函數的go文件)。注意到有這么一行:

p := goFilesPackage(files)

goFilesPackage(files)除了校驗文件類型和后綴,還會入棧,加載,出棧等操作,由于啟動的時候沒有傳遞hello.go,所以系統加載main.go時找不到hello函數,導致報錯。




審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • main
    +關注

    關注

    0

    文章

    38

    瀏覽量

    6168
  • go語言
    +關注

    關注

    1

    文章

    158

    瀏覽量

    9050
收藏 人收藏

    評論

    相關推薦

    Shell腳本命令行解析

    Shell腳本解析命令行參數——Argparse(填坑)
    發表于 04-03 11:34

    cmd網絡經典命令行

    cmd網絡經典命令行:
    發表于 06-11 15:17 ?36次下載
    cmd網絡經典<b class='flag-5'>命令行</b>

    C語言入門教程-命令行參數

    命令行參數 在C中,獲取用戶輸入的命令行參數是很方便的。程序的主函數會接受一個argv參數。有許多高級的庫函數都會用到argv結構,所以了
    發表于 07-29 14:22 ?2614次閱讀

    caxa命令行中的應用

    caxa命令行中的應用 命令行對于大多用戶來說往往只是輸入數據的作用,但是其中的奧妙還有很多,下面就給大家
    發表于 10-18 18:18 ?2299次閱讀

    博達環網配置命令行

    博達工業交換要環網配置命令行
    發表于 12-27 16:24 ?0次下載

    CMD的命令行高級教程

    CMD的命令行高級教程
    發表于 10-24 08:31 ?30次下載
    CMD的<b class='flag-5'>命令行</b>高級教程

    自己動手實現命令行解析

    一、介紹嵌入式里面經常會自己做命令行,這里分享一個命令解析器代碼實現二、代碼實現mycmd.c
    發表于 12-22 18:51 ?13次下載
    自己動手實現<b class='flag-5'>命令行</b><b class='flag-5'>解析</b>器

    如何從命令行獲取和解析參數

    這是一篇技術干貨快文,能夠快速閱讀完。文章內容是關于如何從命令行獲取和解析參數,包括SystemVerilog本身支持的系統函數和UVM提供的函數封裝,并給出示例代碼和仿真結果。
    的頭像 發表于 05-30 14:05 ?2970次閱讀

    uvm命令行傳遞參數的小技巧

    當我們在創建動態仿真case時,使用命令行參數可以非常方便地控制DUT和TB的行為,比如配置寄存器、控制激勵的發送數量、打開或關閉某些scoreboard等。
    的頭像 發表于 08-19 11:53 ?5625次閱讀

    Shell命令行解釋器簡介

    Shell 是一個命令行解釋器,Shell 為用戶提供了與設備進行命令行交互的方式,用戶通過串口、以太網、無線等方式將命令傳輸給具有 Shell 功能的設備,設備會解析
    的頭像 發表于 08-19 17:20 ?3234次閱讀

    Golang基于flag庫實現一個命令行工具

    Golang 標準庫中的 flag 庫提供了解析命令行選項的能力,我們可以基于此來開發命令行工具。
    的頭像 發表于 10-28 09:26 ?1305次閱讀

    Linux命令行與shell腳本編寫

    Linux命令行與shell腳本編寫
    發表于 01-11 16:50 ?4次下載

    介紹Go里面經常使用到的命令行工具

    優秀的工具配合熟練的使用,往往可以讓開發效率大幅度提升,本小節介紹 Go 里面經常使用到的命令行工具。
    的頭像 發表于 05-22 16:58 ?1302次閱讀
    介紹<b class='flag-5'>Go</b>里面經常使用到的<b class='flag-5'>命令行</b>工具

    linux切換到命令行模式

    在Linux中,可以通過以下步驟切換到命令行模式: 打開終端。可以在應用菜單中找到終端或命令行終端。 在終端中輸入命令“exit”或“logout”,然后按回車鍵。 系統會提示您輸入管理員密碼。輸入
    的頭像 發表于 11-13 16:47 ?1791次閱讀

    idea如何輸入命令行參數

    在許多軟件開發和系統管理的任務中,我們經常需要向應用程序傳遞命令行參數命令行參數是在運行時傳遞給程序的值,用于指定程序的行為和配置選項。本文將詳細介紹如何在不同的編程
    的頭像 發表于 12-06 15:01 ?1167次閱讀
    主站蜘蛛池模板: 久久国产露脸老熟女熟69| 国产亚洲精品久久久久久一区二区 | 四虎视频最新视频在线观看| 99在线免费视频| 蜜桃成熟时2电影免费观看d| 亚洲中文字幕国产综合| 韩国电影real在线观看完整版| 兽交白浆喷水高潮| 国产高清美女一级毛片久久| 色精品极品国产在线视频| 高H纯肉NP 弄潮NP男男| 天龙八部慕容属性加点| 国产精品福利电影| 亚洲黄色三级视频| 黄色三级网络| 亚洲欭美日韩颜射在线二| 久cao在线香蕉| 4388成人| 热久久国产欧美一区二区精品| 成年女人免费影院播放| 十次啦中文网| 欧美zozofoot| 国产九九九九九九九A片| 久久视频这里只精品6国产| 影音先锋xfplay影院av| 久久国产露脸老熟女熟69| 中文字幕在线观看网站| 男人女人边摸边吃奶边做| www.久久久| 甜涩性爱下载| 荷兰少归BVBV| 综合色中色| 区产品乱码芒果精品P站在线| 国产精品97久久AV麻豆 | 最近的2019中文字幕国语HD| 久久999视频| 97免费视频观看| 人妖干美女| 国产亚洲精品久久久999无毒| 一级毛片直接看| 欧洲最强rapper潮水喷视频|