go語言的字符串是UTF-8編碼的、不可改變的字節(jié)序列。
立山網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)建站,立山網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為立山1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營銷網(wǎng)站建設(shè)要多少錢,請找那個(gè)售后服務(wù)好的立山做網(wǎng)站的公司定做!
要修改字符串,只能以原串為基礎(chǔ),創(chuàng)建一個(gè)新串。下面的圖中是一個(gè)參考示例,提供了以原串為藍(lán)本,創(chuàng)建新串的兩種方法。
代碼
輸出
? 隨著 2022 年 3 月 15 日 go 1.18 正式發(fā)布,新版本除了對性能的提升之外,還引入了很多新功能,其中就有 go 期盼已久的功能泛型(Generics),同時(shí)還引入的多模塊工作區(qū)(Workspaces)和模糊測試(Fuzzing)。
? 關(guān)于泛型網(wǎng)上已經(jīng)有很多介紹的教程了,這里我介紹一個(gè)實(shí)用的功能,多模塊工作區(qū)的使用方法和教程。
? Go 多模塊工作區(qū)能夠使開發(fā)者能夠更容易地同時(shí)處理多個(gè)模塊的工作,如:
? 多模塊工作區(qū)
? 開發(fā)流程演示
? 總結(jié)
? 參考文獻(xiàn)
? go 使用的是多模塊工作區(qū),可以讓開發(fā)者更容易同時(shí)處理多個(gè)模塊的開發(fā)。在 Go 1.17 之前,只能使用 go.mod replace 指令來實(shí)現(xiàn),如果你正巧是同時(shí)進(jìn)行多個(gè)模塊的開發(fā),使用它可能是很痛苦的。每次當(dāng)你想要提交代碼的時(shí)候,都不得不刪除掉 go.mod 中的 replace 才能使模塊穩(wěn)定的發(fā)布版本。 ?在使用 go 1.18 多模塊工作區(qū)功能的時(shí)候,就使用這項(xiàng)工作變得簡單容易處理。下面我來介紹怎么使用這一功能。? Go 多模塊工作區(qū)文檔、代碼示例[5]
? 首先 我們需要 go 1.18 或更高版本 go 安裝[6]
? 通常情況下,建議不要提交 go.work 文件到 git 上,因?yàn)樗饕糜诒镜卮a開發(fā)。
? 推薦在: $GOPATH 路徑下執(zhí)行,生成 go.work 文件
? go work init 初始化工作區(qū)文件,用于生成 go.work 工作區(qū)文件
? go work use 添加新的模塊到工作區(qū)
? go work edit 用于編輯 go.work 文件
? go work sync 將工作區(qū)的構(gòu)建列表同步到工作區(qū)的模塊
? go env GOWORK
? 文件結(jié)構(gòu)和 go.mod 文件結(jié)構(gòu)類似,支持 Go 版本號、指定工作區(qū)和需要替換的倉庫 ?文件結(jié)構(gòu)示例:
? 可以使用 go work use hello 添加模塊,也可以手動(dòng)修改 go.work 工作區(qū)添加新的模塊 ?在工作區(qū)中添加了模塊路徑,編譯的時(shí)候會(huì)自動(dòng)使用 use 中的本地代碼進(jìn)行代碼編譯,和 replaces 功能類似。
? replaces 命令與 go.mod 指令相同,用于替換項(xiàng)目中依賴的倉庫地址 ?需要注意的是 replaces 和 use 不能同時(shí)指定相同的本地路徑
? 錯(cuò)誤示例
? 在同時(shí)使用 go.work 和 go.mod replace 功能的的時(shí)候分別指定不同的代碼倉庫路徑, go.work 優(yōu)先級高于 go.mod 中定義
? 在代碼構(gòu)建時(shí)候使用的是 go.work 指定的 example1 倉庫的代碼, go.work 優(yōu)先級別更高
? 在 Go 1.18 go run 和 go build 都會(huì)默認(rèn)使用工作區(qū)功能 ? GOWORK 也可以指定配置 go.work 文件位置
? Go 全局變量 GOWORK 設(shè)置 off 則可以禁用工作區(qū)功能
? 演示如何使用多模塊工作區(qū)功能。在現(xiàn)在微服務(wù)盛行的年代,一個(gè)人會(huì)維護(hù)多個(gè)代碼倉庫,很多的時(shí)候是多個(gè)倉庫進(jìn)行同時(shí)開發(fā)
? 假設(shè)我們現(xiàn)在進(jìn)行 hello 倉庫開發(fā),實(shí)現(xiàn)的功能是,實(shí)現(xiàn)將輸入的字符串反轉(zhuǎn)并輸出,字符串反轉(zhuǎn)功能依賴于 github點(diǎn)抗 /link1st/example (下文統(tǒng)稱 example )公共倉庫實(shí)現(xiàn)
? 新建 hello 項(xiàng)目
? main.go 代碼
? 運(yùn)行代碼 go run main.go -str "hello world" 或 go run github點(diǎn)抗 /link1st/link1st/workspaces/hello -str "hello world" 可以看到輸出了 hello world 反轉(zhuǎn)以后的字符串
? 到這里,最初的功能已經(jīng)完成,但是后續(xù)需求變動(dòng),不僅需要輸出反轉(zhuǎn)以后的字符串,還需要將字符串大寫
? 我們則需要去 example 倉庫中添加開發(fā) 將字符串大寫的功能
? vim example/stringutil/to_upper.go 代碼如下
? 由于代碼還在本地調(diào)試,未提交 git 倉庫中,這個(gè)時(shí)候就需要用到 Go 多模塊工作區(qū)的功能了。
? 進(jìn)入項(xiàng)目根目錄,初始化我們現(xiàn)在正在開發(fā)的模塊
? 文件結(jié)構(gòu)如下
? 回到 hello 項(xiàng)目, vim main.go 將字符串大寫的功能添加上。
? 運(yùn)行代碼
? 到這里,演示的代碼已經(jīng)全部完成
? 使用 Go 多模塊工作區(qū)的功能,可以讓我們輕松在多個(gè)模塊之間切換工作,更能適應(yīng)現(xiàn)代微服務(wù)架構(gòu)開發(fā)。
[1] Go 1.18 新特性多模塊工作區(qū)教程:
[2] Go 1.18 is released!:
[3] Tutorial: Getting started with multi-module workspaces:
[4] go-1.18-features:
本教程介紹了 Go 中模糊測試的基礎(chǔ)知識。通過模糊測試,隨機(jī)數(shù)據(jù)會(huì)針對您的測試運(yùn)行,以嘗試找出漏洞或?qū)е卤罎⒌妮斎搿?梢酝ㄟ^模糊測試發(fā)現(xiàn)的一些漏洞示例包括 SQL 注入、緩沖區(qū)溢出、拒絕服務(wù)和跨站點(diǎn)腳本攻擊。
在本教程中,您將為一個(gè)簡單的函數(shù)編寫一個(gè)模糊測試,運(yùn)行 go 命令,并調(diào)試和修復(fù)代碼中的問題。
首先,為您要編寫的代碼創(chuàng)建一個(gè)文件夾。
1、打開命令提示符并切換到您的主目錄。
在 Linux 或 Mac 上:
在 Windows 上:
2、在命令提示符下,為您的代碼創(chuàng)建一個(gè)名為 fuzz 的目錄。
3、創(chuàng)建一個(gè)模塊來保存您的代碼。
運(yùn)行g(shù)o mod init命令,為其提供新代碼的模塊路徑。
接下來,您將添加一些簡單的代碼來反轉(zhuǎn)字符串,稍后我們將對其進(jìn)行模糊測試。
在此步驟中,您將添加一個(gè)函數(shù)來反轉(zhuǎn)字符串。
a.使用您的文本編輯器,在 fuzz 目錄中創(chuàng)建一個(gè)名為 main.go 的文件。
獨(dú)立程序(與庫相反)始終位于 package 中main。
此函數(shù)將接受string,使用byte進(jìn)行循環(huán) ,并在最后返回反轉(zhuǎn)的字符串。
此函數(shù)將運(yùn)行一些Reverse操作,然后將輸出打印到命令行。這有助于查看運(yùn)行中的代碼,并可能有助于調(diào)試。
e.該main函數(shù)使用 fmt 包,因此您需要導(dǎo)入它。
第一行代碼應(yīng)如下所示:
從包含 main.go 的目錄中的命令行,運(yùn)行代碼。
可以看到原來的字符串,反轉(zhuǎn)它的結(jié)果,然后再反轉(zhuǎn)它的結(jié)果,就相當(dāng)于原來的了。
現(xiàn)在代碼正在運(yùn)行,是時(shí)候測試它了。
在這一步中,您將為Reverse函數(shù)編寫一個(gè)基本的單元測試。
a.使用您的文本編輯器,在 fuzz 目錄中創(chuàng)建一個(gè)名為 reverse_test.go 的文件。
b.將以下代碼粘貼到 reverse_test.go 中。
這個(gè)簡單的測試將斷言列出的輸入字符串將被正確反轉(zhuǎn)。
使用運(yùn)行單元測試go test
接下來,您將單元測試更改為模糊測試。
單元測試有局限性,即每個(gè)輸入都必須由開發(fā)人員添加到測試中。模糊測試的一個(gè)好處是它可以為您的代碼提供輸入,并且可以識別您提出的測試用例沒有達(dá)到的邊緣用例。
在本節(jié)中,您將單元測試轉(zhuǎn)換為模糊測試,這樣您就可以用更少的工作生成更多的輸入!
請注意,您可以將單元測試、基準(zhǔn)測試和模糊測試保存在同一個(gè) *_test.go 文件中,但對于本示例,您將單元測試轉(zhuǎn)換為模糊測試。
在您的文本編輯器中,將 reverse_test.go 中的單元測試替換為以下模糊測試。
Fuzzing 也有一些限制。在您的單元測試中,您可以預(yù)測Reverse函數(shù)的預(yù)期輸出,并驗(yàn)證實(shí)際輸出是否滿足這些預(yù)期。
例如,在測試用例Reverse("Hello, world")中,單元測試將返回指定為"dlrow ,olleH".
模糊測試時(shí),您無法預(yù)測預(yù)期輸出,因?yàn)槟鸁o法控制輸入。
但是,Reverse您可以在模糊測試中驗(yàn)證函數(shù)的一些屬性。在這個(gè)模糊測試中檢查的兩個(gè)屬性是:
(1)將字符串反轉(zhuǎn)兩次保留原始值
(2)反轉(zhuǎn)的字符串將其狀態(tài)保留為有效的 UTF-8。
注意單元測試和模糊測試之間的語法差異:
(3)確保新包unicode/utf8已導(dǎo)入。
隨著單元測試轉(zhuǎn)換為模糊測試,是時(shí)候再次運(yùn)行測試了。
a.在不進(jìn)行模糊測試的情況下運(yùn)行模糊測試,以確保種子輸入通過。
如果您在該文件中有其他測試,您也可以運(yùn)行g(shù)o test -run=FuzzReverse,并且您只想運(yùn)行模糊測試。
b.運(yùn)行FuzzReverse模糊測試,查看是否有任何隨機(jī)生成的字符串輸入會(huì)導(dǎo)致失敗。這是使用go test新標(biāo)志-fuzz執(zhí)行的。
模糊測試時(shí)發(fā)生故障,導(dǎo)致問題的輸入被寫入將在下次運(yùn)行的種子語料庫文件中g(shù)o test,即使沒有-fuzz標(biāo)志也是如此。要查看導(dǎo)致失敗的輸入,請?jiān)谖谋揪庉嬈髦写蜷_寫入 testdata/fuzz/FuzzReverse 目錄的語料庫文件。您的種子語料庫文件可能包含不同的字符串,但格式相同。
語料庫文件的第一行表示編碼版本。以下每一行代表構(gòu)成語料庫條目的每種類型的值。由于 fuzz target 只需要 1 個(gè)輸入,因此版本之后只有 1 個(gè)值。
c.運(yùn)行沒有-fuzz標(biāo)志的go test; 新的失敗種子語料庫條目將被使用:
由于我們的測試失敗,是時(shí)候調(diào)試了。
直接將字符變量賦值給整型變量,即可實(shí)現(xiàn)字符到對應(yīng)ASCII碼的轉(zhuǎn)換。
具體實(shí)現(xiàn)方法可以參考如下程序段:
char str[]="abds%*34dfs"; // 定義一個(gè)字符數(shù)組,存放待轉(zhuǎn)換為ASCII碼的字符串
int AsciiNum[20]; // 定義一個(gè)整型數(shù)組,存放字符所對應(yīng)的ASCII碼值,數(shù)組大小根據(jù)字符串長度進(jìn)行設(shè)置
int i;
// 將字符串的每個(gè)字符逐個(gè)賦值給整型數(shù)組AsciiNum,即實(shí)現(xiàn)字符到ASCII碼值的轉(zhuǎn)換
for(i=0; istrlen(str); i++)
{
AsciiNum[i] = str[i]; // 最后數(shù)組AsciiNum就是字符串每個(gè)字符所對應(yīng)ASCII碼值的數(shù)組
}