最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang實(shí)現(xiàn)簡(jiǎn)易的命令行功能

 更新時(shí)間:2023年02月13日 11:20:48   作者:陪我去看海  
這篇文章主要為大家詳細(xì)介紹了如何通過(guò)Golang實(shí)現(xiàn)一個(gè)簡(jiǎn)易的命令行功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下

前言

一次偶然的想法,想知道為什么在終端輸入那些命令行后,就執(zhí)行了對(duì)應(yīng)的操作,這轉(zhuǎn)化為代碼,應(yīng)該怎么實(shí)現(xiàn)呢?

既然有了問(wèn)題,那我們就來(lái)解決問(wèn)題吧!

首先我認(rèn)為想做命令行操作,那就得先”認(rèn)識(shí)“命令行(當(dāng)然這里指你的代碼認(rèn)識(shí)),所以我認(rèn)位有兩個(gè)步驟:

  • 解析命令行
  • 實(shí)現(xiàn)對(duì)應(yīng)命令行的功能

話不多說(shuō)開(kāi)干!

開(kāi)始

正好在學(xué)習(xí) Golang ,那就用它的試試吧!

首先,我們先來(lái)學(xué)習(xí)以下幾個(gè) API

flag.String

// String defines a string flag with specified name, default value, and usage string.
// The return value is the address of an int variable that stores the value of the flag.
// String 定義了一個(gè)字符串標(biāo)志,具有指定的名稱、默認(rèn)值和用法字符串。返回值是存儲(chǔ)標(biāo)志值的字符串變量的地址。
func String(name string, value string, usage string) *string {
	return CommandLine.String(name, value, usage)
}

也就是說(shuō),使用-name value 的命令參數(shù),usage是對(duì)這個(gè)參數(shù)的說(shuō)明,返回值是這個(gè) value 的指針,也就是用戶輸入在 -name 后的 value。

flag.Int

// Int defines an int flag with specified name, default value, and usage string.
// The return value is the address of an int variable that stores the value of the flag.
// Int 定義了一個(gè)具有指定名稱、默認(rèn)值和用法字符串的 int 標(biāo)志。返回值是存儲(chǔ)標(biāo)志值的 int 變量的地址。
func Int(name string, value int, usage string) *int {
	return CommandLine.Int(name, value, usage)
}

使用方式和 String() 一樣,只是類型的區(qū)別。

flag.StringVar

// StringVar defines a string flag with specified name, default value, and usage string.
// The argument p points to a string variable in which to store the value of the flag.
// StringVar 定義了一個(gè)帶有指定名稱、默認(rèn)值和用法字符串的字符串標(biāo)志。參數(shù) p 指向一個(gè)字符串變量,用于存儲(chǔ)標(biāo)志的值。
func StringVar(p *string, name string, value string, usage string) {
	CommandLine.Var(newStringValue(value, p), name, usage)
}

這里可以看到區(qū)別就是,將返回值指針,變成了函數(shù)的第一個(gè)參數(shù)。

flag.IntVar

// IntVar defines an int flag with specified name, default value, and usage string.
// The argument p points to an int variable in which to store the value of the flag.
// IntVar 定義了一個(gè)具有指定名稱、默認(rèn)值和用法字符串的 int 標(biāo)志。參數(shù) p 指向一個(gè)存儲(chǔ)標(biāo)志值的 int 變量。
func IntVar(p *int, name string, value int, usage string) {
	CommandLine.Var(newIntValue(value, p), name, usage)
}

了解這些后,我們就開(kāi)始吧!

定義命令行參數(shù)

package main

// ...import

func commandStyle() {
	methodPtr := flag.String("method", "default", "method of sample")
	valuePtr := flag.Int("value", -1, "value of sample")

	// 解析
	flag.Parse()
	fmt.Println(*methodPtr, *valuePtr)
}

func commandStyle2() {
	var method string
	var value int
	flag.StringVar(&method, "method", "default", "method of sample")
	flag.IntVar(&value, "value", -1, "value of sample")
	flag.Parse()
	fmt.Println(method, value)
}

func main() {
	commandStyle()
}

在終端使用 go run . -method get -value 1 這串命令后,打印出了 get 1。

Parse 解析來(lái)自 os.Args[1:] 的命令行標(biāo)志。必須在定義所有標(biāo)志之后和程序訪問(wèn)標(biāo)志之前調(diào)用。

這里的一個(gè)重要的點(diǎn)就是要使用 flag.Parse(),也就是解析go run .` 之后的標(biāo)志。使用變量將標(biāo)志的值接收,然后打印。

這兩種方式結(jié)果都是一樣,只有寫(xiě)法上的差距,這時(shí)候雖然我們體驗(yàn)了一點(diǎn)簡(jiǎn)單的命令行的影子了,但似乎還是感覺(jué)好像啥效果也沒(méi)有呀。接下來(lái)我們就來(lái)實(shí)現(xiàn)一個(gè) copy 文件內(nèi)容的功能

實(shí)現(xiàn) -f -v 是否強(qiáng)制拷貝

首先我們使用上面說(shuō)過(guò)的類似方式,注冊(cè)標(biāo)志 f,v,然后解析標(biāo)志

func main() {
    var showProgress, force bool
	// -f 當(dāng)存在時(shí)拷貝,是否強(qiáng)制拷貝
	flag.BoolVar(&force, "f", false, "force copy when existing")
	flag.BoolVar(&showProgress, "v", false, "explain what is being done")
	flag.Parse()

	// 獲取參數(shù)個(gè)數(shù),必須要輸入兩個(gè)參數(shù),因?yàn)閏opy是從這個(gè)文件到另一個(gè)文件
	if flag.NArg() < 2 {
		flag.Usage() // 打印用途
		return
	}
    copyFileAction(flag.Arg(0), flag.Arg(1), showProgress, force)
}

注冊(cè)標(biāo)志完成后,我們就可以開(kāi)始實(shí)現(xiàn)我們的 copy 功能了

首先我們必須后面要輸入兩個(gè)文件名,讓最后一個(gè)文件copy到前一個(gè)文件(制定規(guī)則)

我們模擬命令行輸入:go run . -f -v a.txt b.txt ,這就是我們最后需要實(shí)現(xiàn)的東西,f, v是可以省略的,默認(rèn)把 a.txt -> b.txt。

  • -f表示當(dāng)文件存在時(shí),強(qiáng)制copy覆蓋里面的內(nèi)容
  • -v表示解釋正在做什么

接下來(lái)我們需要實(shí)現(xiàn)一個(gè) copyFileAction 函數(shù),來(lái)實(shí)現(xiàn)copy功能,以及命令行參數(shù)的效果

copyFileAction 實(shí)現(xiàn)

func fileExist(fileName string)bool {
	_, err := os.Stat(fileName) // 返回這個(gè)文件信息
	// IsExist 只是錯(cuò)誤或報(bào)告是否存在
	// err == nil,表示有文件信息,os.IsExist(err),表示有文件存在
	return err == nil || os.IsExist(err)
}

// 轉(zhuǎn)化操作,命令行,與功能實(shí)現(xiàn)的邏輯判斷
func copyFileAction(src, dst string, showProgress, force bool) {
	if !force {
		// 判斷是否存在文件,若存在,是否需要覆蓋它
		if fileExist(dst) {
			fmt.Printf("%s exists override? y/n \n", dst)
			reader := bufio.NewReader(os.Stdin) // 讀取輸入內(nèi)容
			data, _, _ := reader.ReadLine() // 取一行的內(nèi)容
			// 判斷輸入的內(nèi)容
			if strings.TrimSpace(string(data)) != "y" {
				return
			}
		}
	}
    // copy 文件
	copyFile(src, dst)
}

這里我們可以看到充分利用到了 showProgress 和 force 兩個(gè)命令行取的值,當(dāng)文件``存在且不強(qiáng)制`時(shí),會(huì)有一個(gè)詢問(wèn),是否覆蓋,同意就實(shí)行 copy 操作,不同意不做處理(相當(dāng)于一次無(wú)效命令)。

接下來(lái)我們實(shí)現(xiàn)功能核心 copyFile

copyFile

func copyFile(originFile, targetFile string)(written int64, err error){
	srcFile, err := os.Open(originFile) // 打開(kāi)文件
	if err != nil {
		// Error() 返回錯(cuò)誤信息
		log.Fatal(err)
		return
	}
	defer srcFile.Close()
	dstFile, err := os.Create(targetFile) // 創(chuàng)建文件
	if err != nil {
		// Error() 返回錯(cuò)誤信息
		log.Fatal(err)
		return
	}
	defer dstFile.Close()
	return io.Copy(dstFile, srcFile) // 拷貝文件
}

這里我們是采取,將需要被拷貝的文件打開(kāi),拷貝到的文件名進(jìn)行創(chuàng)建,然后將內(nèi)容填充進(jìn)去,這里使用了io.Copy() 的內(nèi)置功能。

效果圖

完整代碼

package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strings"
)

// func commandStyle() {
// 	methodPtr := flag.String("method", "default", "method of sample")
// 	valuePtr := flag.Int("value", -1, "value of sample")

// 	// 解析
// 	flag.Parse()
// 	fmt.Println(*methodPtr, *valuePtr)
// }

// func commandStyle2() {
// 	var method string
// 	var value int
// 	flag.StringVar(&method, "method", "default", "method of sample")
// 	flag.IntVar(&value, "value", -1, "value of sample")
// 	flag.Parse()
// 	fmt.Println(method, value)
// }

func main() {
	// commandStyle()
	// commandStyle2()
	var showProgress, force bool
	// -f 當(dāng)存在時(shí)拷貝,是否強(qiáng)制拷貝
	flag.BoolVar(&force, "f", false, "force copy when existing")
	flag.BoolVar(&showProgress, "v", false, "explain what is being done")
	flag.Parse()

	// 獲取參數(shù)個(gè)數(shù)
	if flag.NArg() < 2 {
		flag.Usage() // 打印用途
		return
	}
	copyFileAction(flag.Arg(0), flag.Arg(1), showProgress, force)
}

func fileExist(fileName string)bool {
	_, err := os.Stat(fileName) // 返回這個(gè)文件信息
	// IsExist 只是錯(cuò)誤或報(bào)告是否存在
	// err == nil,表示有文件信息,os.IsExist(err),表示有文件存在
	return err == nil || os.IsExist(err)
}

func copyFile(originFile, targetFile string)(written int64, err error){
	srcFile, err := os.Open(originFile) // 打開(kāi)文件
	if err != nil {
		// Error() 返回錯(cuò)誤信息
		log.Fatal(err)
		return
	}
	defer srcFile.Close()
	dstFile, err := os.Create(targetFile) // 創(chuàng)建文件
	if err != nil {
		// Error() 返回錯(cuò)誤信息
		log.Fatal(err)
		return
	}
	defer dstFile.Close()
	return io.Copy(dstFile, srcFile) // 拷貝文件
}

// 拷貝文件
func copyFileAction(src, dst string, showProgress, force bool) {
	if !force {
		// 判斷是否存在文件,若存在,是否需要覆蓋它
		if fileExist(dst) {
			fmt.Printf("%s exists override? y/n \n", dst)
			reader := bufio.NewReader(os.Stdin) // 讀取輸入內(nèi)容
			data, _, _ := reader.ReadLine() // 取一行的內(nèi)容
			// 判斷輸入的內(nèi)容
			if strings.TrimSpace(string(data)) != "y" {
				return
			}
		}
	}
	// copy 文件
	copyFile(src, dst)
}

以上就是Golang實(shí)現(xiàn)簡(jiǎn)易的命令行功能的詳細(xì)內(nèi)容,更多關(guān)于Golang命令行功能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • go語(yǔ)言題解LeetCode1275找出井字棋的獲勝者示例

    go語(yǔ)言題解LeetCode1275找出井字棋的獲勝者示例

    這篇文章主要為大家介紹了go語(yǔ)言題解LeetCode1275找出井字棋的獲勝者示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Go語(yǔ)言性能監(jiān)控和調(diào)優(yōu)的工具和方法

    Go語(yǔ)言性能監(jiān)控和調(diào)優(yōu)的工具和方法

    本文介紹了Go語(yǔ)言性能監(jiān)控和調(diào)優(yōu)的工具和方法,包括?pprof、expvar?和?trace?等工具的使用方法和注意事項(xiàng),以及性能調(diào)優(yōu)的一些常見(jiàn)方法,如減少內(nèi)存分配、避免頻繁的垃圾回收、避免過(guò)度查詢數(shù)據(jù)庫(kù)等,針對(duì)不同的程序,應(yīng)該根據(jù)實(shí)際情況采用不同的優(yōu)化方法
    2024-01-01
  • Golang實(shí)現(xiàn)Trie(前綴樹(shù))的示例

    Golang實(shí)現(xiàn)Trie(前綴樹(shù))的示例

    本文主要介紹了Golang實(shí)現(xiàn)Trie(前綴樹(shù))的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • golang查看CPU使用率與內(nèi)存的方法詳解

    golang查看CPU使用率與內(nèi)存的方法詳解

    這篇文章主要給大家介紹了golang查看CPU使用率與內(nèi)存的方法,以及拓展介紹源碼里//go:指令,文中有詳細(xì)的代碼示例以及圖文介紹,需要的朋友可以參考下
    2023-10-10
  • Go代碼格式化gofmt的使用方法實(shí)例

    Go代碼格式化gofmt的使用方法實(shí)例

    Golang制定了統(tǒng)一的官方代碼風(fēng)格,并推出gofmt工具(go fmt)來(lái)幫助開(kāi)發(fā)人員格式化代碼到統(tǒng)一的風(fēng)格,下面這篇文章主要給大家介紹了關(guān)于Go代碼格式化gofmt的使用方法,需要的朋友可以參考下
    2023-04-04
  • Golang Cron 定時(shí)任務(wù)的實(shí)現(xiàn)示例

    Golang Cron 定時(shí)任務(wù)的實(shí)現(xiàn)示例

    這篇文章主要介紹了Golang Cron 定時(shí)任務(wù)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 深入探討Golang中如何進(jìn)行并發(fā)發(fā)送HTTP請(qǐng)求

    深入探討Golang中如何進(jìn)行并發(fā)發(fā)送HTTP請(qǐng)求

    在?Golang?領(lǐng)域,并發(fā)發(fā)送?HTTP?請(qǐng)求是優(yōu)化?Web?應(yīng)用程序的一項(xiàng)重要技能,本文探討了實(shí)現(xiàn)此目的的各種方法,文中的示例代碼講解詳細(xì),希望對(duì)大家有所幫助
    2024-01-01
  • 自定義Go?Json的序列化方法譯文

    自定義Go?Json的序列化方法譯文

    這篇文章主要為大家介紹了自定義Go?Json序列化方法譯文,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • golang字符串本質(zhì)與原理詳解

    golang字符串本質(zhì)與原理詳解

    這篇文章主要介紹了golang字符串本質(zhì)與原理詳解,golang中的字符串指的是所有8比特位字節(jié)字符串的集合,通常是UTF-8編碼的文本,更多相關(guān)內(nèi)容需要的小伙伴可以參考一下
    2022-06-06
  • Go中string與[]byte高效互轉(zhuǎn)的方法實(shí)例

    Go中string與[]byte高效互轉(zhuǎn)的方法實(shí)例

    string與[]byte經(jīng)常需要互相轉(zhuǎn)化,普通轉(zhuǎn)化會(huì)發(fā)生底層數(shù)據(jù)的復(fù)制,下面這篇文章主要給大家介紹了關(guān)于Go中string與[]byte高效互轉(zhuǎn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-09-09

最新評(píng)論

江孜县| 甘肃省| 磐石市| 潍坊市| 武川县| 西乌| 开封市| 鄂托克旗| 清水县| 阜南县| 静宁县| 青田县| 溆浦县| 吐鲁番市| 宁国市| 尉氏县| 玉林市| 布尔津县| 纳雍县| 乐东| 木里| 大渡口区| 平武县| 三原县| 香格里拉县| 固始县| 海原县| 广南县| 商水县| 司法| 瑞丽市| 南郑县| 衡阳市| 连城县| 云林县| 崇州市| 五原县| 什邡市| 奇台县| 上饶市| 蒲城县|