版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、Go 基礎(chǔ)鞏固加強指針指針是一個代表著某個內(nèi)存地址的值。這個內(nèi)存地址往往是在內(nèi)存中存儲的另一個變量的值的起始位置。Go 語言對指針的支持介于 Java 語言和C/C+語言之間,它既沒有想 Java 語言那樣取消了代碼對指針的直接操作的能力,也避免了 C/C+語言中由于對指針的而造成的安全和可靠性問題。Go 語言中的指針Go 語言保留了指針,但與 C 語言指針有所不同。主要體現(xiàn)在:默認(rèn)值 nil操作符 & 取變量地址, * 通過指針訪問目標(biāo)對象不支持指針運算,不支持 - 運算符,直接 . 訪問目標(biāo)成員函數(shù) new表達(dá)式 new(T)將創(chuàng)建一個 T 類型的變量,所做的是為 T 類型的新值分配并清零
2、一塊內(nèi)存空間,然后將這塊內(nèi)存空間的地址作為結(jié)果返回,而這個結(jié)果就是指向這個新的 T 類型值的指針值,返回的指針類型為*T。new 創(chuàng)建的內(nèi)存空間位于 heap 上,空間的默認(rèn)值為數(shù)據(jù)類型默認(rèn)值。如:new(int) 則 *p 為 0,new(bool) 則*p 為 falsefunc main() var p1 *int p1 = new(int) /p1 為 *int 類 型 , 指向的 int 變量 fmt.Println(*p1 = , *p1) /*p1 = 0 p2 := new(bool)/p2 為*bool 類型, 指向的 bool 變量 fmt.Println(*p2 = ,
3、*p2) /*p2 = false func main() var a int = 100 / 聲 明 int 變 量 a fmt.Printf(&a = %pn, &a) / & 取 a 地 址 var p *int = nil/ 聲明變量 p, 類型為 *int p = &a/ p 指向 a fmt.Printf(p = %pn, p) fmt.Printf(a = %d, *p = %dn, a, *p) *p = 324/*p 操作指針?biāo)赶虻膬?nèi)存,即為 a fmt.Printf(a = %d, *p = %dn, a, *p) 我們只需使用 new()函數(shù),無需擔(dān)心其內(nèi)存的生命周期或
4、怎樣將其刪除,因為 Go 語言的內(nèi)存管理系統(tǒng)會幫我們打理一切。指針做函數(shù)參數(shù)slice切片簡述數(shù)組的長度在定義之后無法再次修改;數(shù)組是值類型,每次傳遞都將產(chǎn)生一份副本。顯然這種數(shù)據(jù)結(jié)構(gòu)無法完全滿足開發(fā)者的真實需求。Go 語言提供了數(shù)組切片(slice)來彌補數(shù)組的不足。Slice(切片)代表變長的序列,序列中每個元素都有相同的類型。一個 slice 類型一般寫作T,其中 T 代表 slice中元素的類型;slice 的語法和數(shù)組很像,只是沒有固定長度而已。數(shù)組和 slice 之間有著緊密的聯(lián)系。一個 slice 是一個輕量級的數(shù)據(jù)結(jié)構(gòu),提供了訪問數(shù)組子序列(或者全部)元素的功能,而且 slic
5、e 的底層確實引用一個數(shù)組對象。一個 slice 由三個部分構(gòu)成:指針、長度和容量。指針指向第一個 slice 元素對應(yīng)的底層數(shù)組元素的地址,要注意的是 slice 的第一個元素并不一定就是數(shù)組的第一個元素。切片并不是數(shù)組或數(shù)組指針,它通過內(nèi)部指針和相關(guān)屬性引數(shù)組段,以實現(xiàn)變案。func swap01(a, b int) a, b = b, afmt.Printf(swap01 a = %d, b = %dn, a, b)func swap02(x, y *int) *x, *y = *y, *xfunc main() a := 10b := 20/swap01(a, b)/值傳遞(傳值) s
6、wap02(&a, &b)/地址傳遞(傳引用) fmt.Printf(a = %d, b = %dn, a, b) *p2 = true fmt.Println(*p2 = , *p2) /*p1 = true slice 并不是真正意義上的動態(tài)數(shù)組,而是一個引用類型。slice 總是指向一個底層 array,slice 的聲明也可以像array 一樣,只是不需要長度。創(chuàng)建切片slice 和數(shù)組的區(qū)別:聲明數(shù)組時, 內(nèi)寫明了數(shù)組的長度或使用.自動計算長度,而聲明 slice 時, 內(nèi)沒有任何字符。經(jīng)常使用的切片創(chuàng)建方法:1.自動推導(dǎo)類型創(chuàng)建 slices1 := int 1, 2, 3, 4創(chuàng)
7、建 有 4 個元素的切片,分別為:12342.借助 make 創(chuàng)建 slice,格式:make(切片類型,長度,容量)s2 := make(int, 5, 10) len(s2) = 5, cap(s2) = 103.make 時,沒有指定容量,那么 長度=容量s3 := make(int, 5)len(s3) = 5, cap(s3) = 5注意:make 只能創(chuàng)建 slice、map 和 channel,并且返回一個有初始值(非零)的對象。func main() s1 := int 1, 2, 3, 4 / 創(chuàng)建 有 4 個元素的切片 fmt.Println(s1=, s1) s2 :=
8、make(int, 5, 10) / 借助 make 創(chuàng)建 slice,格式:make(切片類型,長度,容量) s24 = 7 /s25 = 9/ 報錯:panic: runtime error: index out of range fmt.Println(s2=, s2) fmt.Printf(len(s2)=%d, cap(s2)=%dn, len(s2), cap(s2) s3 := make(int, 5) / make 時,沒指定容量,那么 長度 = 容量 s32 = 3 fmt.Println(s3=, s3) fmt.Printf(len(s2)=%d, cap(s2)=%dn
9、, len(s3), cap(s3) 切片操作切片截取截取可表示為 slow:high:max。low:表示下標(biāo)的起點。 high:表示下標(biāo)的終點(左閉右開,不包括此下標(biāo))。長度 len = high low。容量 cap = max low。長度對應(yīng) slice 中元素的數(shù)目;長度不能超過容量,容量一般是從 slice的開始位置到底層數(shù)據(jù)的結(jié)尾位置。內(nèi)置的 len()和 cap() 函數(shù)分別返回 slice 的長度和容量。示例說明:切片和底層數(shù)組關(guān)系func main() arr := int 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 s1 := arr2:5/ 從 arr2
10、開始,取 5-2 個元素,組成切片 s1。 fmt.Println(s1=, s1)/ s1= 2 3 4 s11 = 666/ 這樣將 arr 數(shù)組中 3 - 666。 fmt.Println(arr=, arr)/ arr= 0 1 2 666 4 5 6 7 8 9 s2 := s12:7/ 從 s12開始, 取 7-2 個元素,組成 s2。 fmt.Println(s2=, s2)/ 實際上還是取的 數(shù)組 arr。 s2= 4 5 6 7 8 s22 = 777/ 這會將 arr 中的 6 - 777 操作結(jié)果lencap說明array:6:8array5:array:3array:0
11、 1 2 3 4 55 6 7 8 90 1 20 1 2 3 4 5 6 7 8 965310851010省略 low省略 high、 max 省略 high、 max 全部省略array := int0, 1, 2, 3, 4, 5, 6, 7, 8, 9操作含義sn s:slow:s:high slow:highslow : high : maxlen(s)cap(s)切片 s 中索引位置為 n 的項從切片 s 的索引位置 0 到 len(s)-1 處所獲得的切片從切片 s 的索引位置 low 到 len(s)-1 處所獲得的切片從切片 s 的索引位置 0 到 high 處所獲得的切片,
12、len=high從切片 s 的索引位置 low 到 high 處所獲得的切片,len=high-low 從切片 s 的索引位置 low 到 high 處所獲得的切片,len=high-low,cap=max-low切片 s 的長度,總是=len(s)利用數(shù)組創(chuàng)建切片。切片在操作過程中,是直接操作原數(shù)組。切片是數(shù)組的引用!因此,在 go 語言中,我們常常使用切片代替數(shù)組。切片做函數(shù)參數(shù)切片作為函數(shù)參數(shù)時,傳引用。常用操作函數(shù)append 函數(shù)append() 函數(shù)可以向slice 尾部添加數(shù)據(jù),可以自動為切片擴容。常常會返回新的slice 對象:append 函數(shù)會智能的將底層數(shù)組的容量增長,一
13、旦超過原底層數(shù)組容量,通常以 2 倍(1024 以下)容量重新分配底層數(shù)組,并復(fù)制原來的數(shù)據(jù)。因此,使用 append 給切片做擴充時,切片的地址可能發(fā)生變化。但,數(shù)據(jù)都被重新保存了,不影響使用。var s1 int/創(chuàng)建 nil 切片,或者:s1 := make(int, 0)s1 = append(s1, 1)/追加 1 個元素s1 = append(s1, 2, 3)/追加 2 個元素s1 = append(s1, 4, 5, 6)/追加 3 個元素fmt.Println(s1)/1 2 3 4 5 6s2 := make(int, 5) s2 = append(s2, 6)fmt.Pr
14、intln(s2)/0 0 0 0 0 6s3 := int1, 2, 3s3 = append(s3, 4, 5)fmt.Println(s3)/1 2 3 4 5func testFunc(s int) / 切片做函數(shù)參數(shù) s0 = -1/ 直接修改 main 中的 slice func main() slice := int0, 1, 2, 3, 4, 5, 6, 7, 8, 9 fmt.Println(slice) testFunc(slice) / 傳 引 用 fmt.Println(slice) fmt.Println(arr=, arr)/ arr= 0 1 2 666 4 5
15、777 7 8 9 輸出結(jié)果如下:cap: 1 - 2cap: 2 - 4cap: 4 - 8cap: 8 - 16cap: 16 - 32cap: 32 - 64cap: 64 - 128練習(xí) 1:給定一個字符串列表,在原有 slice 上返回不包含空字符串的列表, 如:red, , black, , , pink, blue red, black, pink, blue練習(xí) 2:寫一個函數(shù),就地消除string 中重復(fù)字符串,如:red, black, red, pink, blue, pink, blue red, black, pink, blue copy 函數(shù)函數(shù) copy 在兩個
16、 slice 間復(fù)制數(shù)據(jù),復(fù)制度以 len 小的為準(zhǔn),兩個 slice 指向同底層數(shù)組。直接對應(yīng)位置覆蓋。練習(xí) 3:要刪除 slice 中間的某個元素并保存原有的元素順序, 如:5, 6, 7, 8, 9 5, 6, 8, 9 data := .int0, 1, 2, 3, 4, 5, 6, 7, 8, 9s1 := data8:/8, 9s2 := data:5/0, 1, 2, 3, 4copy(s2, s1)/ dst:s2, src:s1fmt.Println(s2)/8 9 2 3 4fmt.Println(data)/8 9 2 3 4 5 6 7 8 9func main() s
17、 := make(int, 0, 1) c := cap(s) for i := 0; i c fmt.Printf(cap: %d - %dn, c, n) c = n mapmap 簡述Go 語言中的 map(映射、字典)是一種內(nèi)置的數(shù)據(jù)結(jié)構(gòu),它是一個無序的 key-value 對的集合,比如以號作為唯一鍵來標(biāo)識一個人的信息。Go 語言中并沒有提供一個 set 類型,但是 map 中的 key 也是不相同的,可以用map 實現(xiàn)類似 set 的功能。map 格式為:在一個 map 里所有的鍵都是唯一的,而且必須是支持=和!=操作符的類型,切片、函數(shù)以及包含切片的結(jié)構(gòu)類型這些類型由于具有引用語
18、義,不能作為映射的鍵,使用這些類型會造成編譯錯誤:map 值可以是任意類型,沒有限制。map 里所有鍵的數(shù)據(jù)類型必須是相同的,值也必須如此,但鍵和值的數(shù)據(jù)類型可以不相同。注意:map 是無序的,我們無法決定它的返回順序,所以,每次打印結(jié)果的順利有可能不同。創(chuàng)建、初始化 map創(chuàng)建 mapvar m1 mapintstring/只是聲明一個 map,沒有初始化, 為空(nil)map fmt.Println(m1 = nil) /true/m11 = Luffy/nil 的 map 不能使用 err, panic: assignment to entry in nil mapm2 := mapi
19、ntstring /m2, m3 的創(chuàng)建方法是等價的m3 := make(mapintstring)fmt.Println(m2, m3)/map mapdict := map string int /err, invalid map key type stringmapkeyTypevalueType創(chuàng)建 m4 的方法指定了 map 的初始創(chuàng)建容量。 與 slice 類似,后期在使用過程中,map 可以自動擴容。只不過map 更方便一些,不用借助類似 append 的函數(shù),直接賦值即可。如,m117 = Nami。賦值過程中,key 如果與已有 map 中key 重復(fù),會將原有 map 中k
20、ey 對應(yīng)的 value 覆蓋。但是!對于 map 而言,可以使用 len()函數(shù),但不能使用 cap()函數(shù)。初始化 map也可以直接指定初值,要保證 key 不重復(fù)。常用操作賦值遍歷Map 的迭代順序是不確定的,并且不同的哈希函數(shù)實現(xiàn)可能導(dǎo)致不同的遍歷順序。在實踐中,遍歷的順序是隨機的,每一次遍歷的順序都不相同。這是故意的,每次都使用隨機的遍歷順序可以強制要求程序不會依賴具體的哈希函數(shù)實現(xiàn)。m1 := mapintstring1: Luffy, 2: Sanji/遍歷 1,第一個返回值是 key,第二個返回值是 valuem1 := mapintstring1: Luffy, 2: San
21、ji m11 = Nami/修改m13 = Zoro/追加, go 底層會自動為 map 分配空間fmt.Println(m1) /map1:Nami 2:Sanji 3:Zorom2 := make(mapintstring, 10)/創(chuàng)建 map m20 = aaam21 = bbbfmt.Println(m2)/map0:aaa 1:bbbfmt.Println(m20, m21)/aaa bbb/1、定義同時初始化var m1 mapintstring = mapintstring1: Luffy, 2: Sanji fmt.Println(m1) /map1:Luffy 2:Sanj
22、i/2、自動推導(dǎo)類型 :=m2 := mapintstring1: Luffy, 2: Sanjifmt.Println(m2)m4 := make(mapintstring, 10)/第 2 個參數(shù)指定容量fmt.Println(m4)/map有時候可能需要知道對應(yīng)的元素是否真的是在 map 之中??梢允褂孟聵?biāo)語法判斷某個 key 是否存在。map 的下標(biāo)語法將產(chǎn)生兩個值,其中第二個是一個布爾值,用于報告元素是否真的存在。如果 key 存在,第一個返回值返回 value 的值。第二個返回值為 true。如果 key 不存在,第一個返回值為空,第二個返回值為 false。刪除使用 delete
23、()函數(shù),指定 key 值可以方便的刪除 map 中的k-v 映射。delete()操作是安全的,即使元素不在 map 中也沒有關(guān)系;如果查找刪除失敗將返回 value 類型對應(yīng)的零值。m1 := mapintstring1: Luffy, 2: Sanji, 3: Zorofor k, v := range m1 /遍歷,第一個返回值是 key,第二個返回值是 value fmt.Printf(%d - %sn, k, v)/1 - Sanji/2 - Sanji/3 - Zorodelete(m1, 2)/刪除 key 值為 2 的 mapfor k, v := range m1 fmt.
24、Printf(%d - %sn, k, v)/1 - Luffy/3 - Zorovalue2, has := m13fmt.Println(value2 = , value2, , has = , has) /value2 =, has = falsevalue, ok := m11fmt.Println(value = , value, , ok = , ok) /value = mike , ok = truefor k, v := range m1 fmt.Printf(%d - %sn, k, v)/1 - Luffy/2 - yoyo/遍歷 2,第一個返回值是 key,第二個返回值
25、是 value(可省略)for k := range m1 fmt.Printf(%d - %sn, k, m1k)/1 - Luffy/2 - Sanji如:map 輸出結(jié)果依然是原來的樣子,且不會有任何錯誤提示。map 做函數(shù)參數(shù)與 slice相似,在函數(shù)間傳遞映射并不會制造出該映射的一個副本,不是值傳遞,而是引用傳遞:map 做函數(shù)返回值返回的依然是引用:func test() mapintstring / m1 := mapintstring1: Luffy, 2: Sanji, 3: Zoro m1 := make(mapintstring, 1) / 創(chuàng)建一個初創(chuàng)容量為 1 的 m
26、ap m11 = Luffy m12 = Sanji / 自 動 擴 容 m167 = Zoro m12 = Nami/ 覆蓋 key 值為 2 的 map fmt.Println(m1 = , m1) func DeleteMap(m mapintstring, key int) delete(m, key) /刪除 key 值為 2 的 mapfor k, v := range m fmt.Printf(len(m)=%d, %d - %sn, len(m), k, v)/len(m)=2, 1 - Luffy/len(m)=2, 3 - Zorofunc main() m := mapi
27、ntstring1: Luffy, 2: Sanji, 3: ZoroDeleteMap(m, 2)/刪除 key 值為 2 的 mapfor k, v := range m fmt.Printf(len(m)=%d, %d - %sn, len(m), k, v)/len(m)=2, 1 - Luffy/len(m)=2, 3 - Zorodelete(m1, 5)/刪除 key 值為 5 的 mapfor k, v := range m1 fmt.Printf(%d - %sn, k, v)/1 - Luffy/3 - Zoro輸出:m1 =map1:Luffy 2:Nami 67:Zor
28、om2 =map2:Nami 67:Zoro 1:Luffy練習(xí) 3: 封裝 wcFunc() 函數(shù)。接收一段英文字符串 str。返回一個 map,記錄 str 中每個“詞”出現(xiàn)次數(shù)的。如:I love my work and I love my family too輸出:family : 1too : 1I : 2love : 2my : 2work : 1and : 1提示:使用 strings.Fields() 函數(shù)可提高效率。結(jié)構(gòu)體結(jié)構(gòu)體類型有時我們需要將不同類型的數(shù)據(jù)組合成一個有機的整體,如:一個學(xué)生有學(xué)號/姓名/性別/年齡/地址等屬性。顯然單獨定義以上變量比較繁瑣,數(shù)據(jù)不便于管理。
29、結(jié)構(gòu)體是一種聚合的數(shù)據(jù)類型,它是由一系列具有相同類型或不同類型的數(shù)據(jù)構(gòu)成的數(shù)據(jù)集合。每個數(shù)據(jù)稱為結(jié)構(gòu)體的成員。 return m1 func main() m2 := test()/ 返回值 傳引用 fmt.Println(m2 = , m2) 結(jié)構(gòu)體初始化普通變量指針變量使用結(jié)構(gòu)體成員普通變量/=結(jié)構(gòu)體變量為普通變量/1、打印成員var s1 Student = Student1, Luffy, m, 18, EastSea/結(jié)果:id = 1, name = Luffy, sex = m, age = 18, addr = EastSeafmt.Printf(id = %d, name =
30、 %s, sex = %c, age = %d, addr = %sn, s1.id, , s1.sex, s1.age, s1.addr)type Student struct idintname string sex byte age int addr stringfunc main() var s5 *Student = &Student3, Nami, m, 16, EastSea s6 := &Student4, ro, m, 3, NorthSeatype Student struct idintname string sex byte age int addr st
31、ringfunc main() /1、順序初始化,必須每個成員都初始化var s1 Student = Student1, Luffy, m, 18, EastSea s2 := Student2, Sanji, f, 20, EastSea/s3 := Student2, Nami, m, 20 /err, too few values in struct initializer/2、指定初始化某個成員,沒有初始化的成員為零值s4 := Studentid: 2, name: Zoro指針變量在 Go 語言中,普通結(jié)構(gòu)體變量和 結(jié)構(gòu)體指針變量發(fā)訪問成員的方法一致。不需要加以區(qū)分。結(jié)構(gòu)體比較如
32、果結(jié)構(gòu)體的全部成員都是可以比較的,那么結(jié)構(gòu)體也是可以比較的,那樣的話兩個結(jié)構(gòu)體將可以使用 =或 != 運算符進(jìn)行比較,但不支持 或 。func main() s1 := Student1, Luffy, m, 18, EastSeas2 := Student1, Luffy, m, 18, EastSeafmt.Println(s1 = s2, s1 = s2) /s1 = s2 true fmt.Println(s1 != s2, s1 != s2) /s1 != s2 false/=結(jié)構(gòu)體變量為指針變量/3、先分配空間,再賦值s3 := new(Student) s3.id = 3s3.n
33、ame = Namifmt.Println(s3) /&3 Nami 0 0 /4、普通變量和指針變量類型打印var s4 Student = Student4, Sanji, m, 18, EastSeafmt.Printf(s4 = %v, &s4 = %vn, s4, &s4) /s4 = 4 Sanji 109 18 sz, &s4 = &4 Sanji 109 18 EastSeavar p *Student = &s4/p.成員 和(*p).成員 操作是等價的p.id = 5 (*p).name = rofmt.Println(p, *p, s4) /&5 ro 109 18 Ea
34、stSea 5 ro 109 18 EastSea 5 ro 109 18EastSea/2、成員變量賦值var s2 Student s2.id = 2 = Sanji s2.sex = f s2.age = 16s2.addr = EastSeafmt.Println(s2) /2 yoyo 102 16 EastSea作函數(shù)參數(shù)傳值傳參過程中,實參會將自己的值拷貝一份給形參。因此結(jié)構(gòu)體“傳值”操作幾乎不會在實際開發(fā)中被使用到。近乎 100%的使用都采用“傳址”的方式,將結(jié)構(gòu)體的引用傳遞給所需函數(shù)。傳引用文件操作字符串處理函數(shù)字符串在開發(fā)中使用頻率較高,我們經(jīng)常需要對字符串
35、進(jìn)行拆分、判斷等操作,可以借助 Go 標(biāo)準(zhǔn)庫中的 strings包快速達(dá)到處理字符串的目錄。除Contains、Join、Trim、Replace 等我們學(xué)過的字符串處理函數(shù)之外,以下函數(shù)也常常會被用到。字符串分割func Split(s, sep string) string功能:把 s 字符串按照 sep 分割,返回 slicefunc printPointer(p *Student) p.id = 250/printPointer p = &250 Luffy 109 18 EastSea fmt.Println(printPointer p = , p)func main() var
36、s Student = Student1, Luffy, m, 18, EastSeaprintPointer(&s)/傳引用(地址),形參修改會影響到實參值fmt.Println(main s = , s) /main s = 250 Luffy 109 18 EastSeafunc printValue(stu Student) stu.id = 250/printValue stu = 250 Luffy 109 18 s EastSea fmt.Println(printValue stu = , stu)func main() var s Student = Student1, Lu
37、ffy, m, 18, EastSeaprintValue(s)/值傳遞,形參修改不會影響到實參值fmt.Println(main s = , s) /main s = 1 Luffy 109 18 EastSea參 1:s,表示待拆分的字符串參 2:sep,表示分割符,該參數(shù)為 string 類型返回值:切片,存儲拆分好的子串示例代碼:按空格拆分字符串參 1:s,表示待拆分的字符串返回值:切片,存儲拆分好的子串示例代碼:判斷字符串后綴參 1:s,表示待判定字符串參 2:suffix,表示前綴子串返回值:true or false示例代碼:判斷字符串前綴func HasPrefix(s, pr
38、efix string) bool功能:判斷 s 字符串是否有前綴子串 suffixfmt.Printf(%vn, strings.HasSuffix(World Cup.png, .png)/運行結(jié)果:truefunc HasSuffix(s, suffix string) bool功能:判斷 s 字符串是否有后綴子串 suffixfmt.Printf(Fields are: %q, strings.Fields( foo barbaz)/運行結(jié)果:Fields are: foo bar bazfunc Fields(s string) string功能:去除 s 字符串的空格符,并且按照空
39、格分割,返回 slicefmt.Printf(%qn, strings.Split(a,b,c, ,)fmt.Printf(%qn, strings.Split(a man a plan a canal panama, a ) fmt.Printf(%qn, strings.Split( xyz , )fmt.Printf(%qn, strings.Split(, Bernardo OHiggins)/運行結(jié)果:/a b c/ man plan canal panama/ x y z /參 1:s,表示待判定字符串參 2:prefix,表示前綴子串返回值:true or false示例代碼:文
40、件操作常用 API建立與打開文件新建文件可以通過如下兩個方法:通過如下兩個方法來打開文件:Open()是以只讀權(quán)限打開文件名為 name 的文件,得到的文件指針 file,只能用來對文件進(jìn)行“讀”操作。如果我們有“寫”文件的需求,就需要借助 Openfile 函數(shù)來打開了。OpenFile()可以選擇打開 name 文件的讀寫權(quán)限。這個函數(shù)有三個默認(rèn)參數(shù):參 1:name,表示打開文件的路徑??墒褂孟鄬β窂?或 絕對路徑參 2:flg,表示讀寫模式,常見的模式有:O_RDONLY(只讀模式), O_WRONLY(只寫模式), O_RDWR(可讀可寫模式), O_APPEND(追加模式)。參 3
41、:perm,表權(quán)限取值范圍(0-7),表示如下:0:沒有任何權(quán)限1:執(zhí)行權(quán)限(如果是可執(zhí)行文件,是可以運行的)2:寫權(quán)限3: 寫權(quán)限與執(zhí)行權(quán)限4:讀權(quán)限5: 讀權(quán)限與執(zhí)行權(quán)限6: 讀權(quán)限與寫權(quán)限7: 讀權(quán)限,寫權(quán)限,執(zhí)行權(quán)限func OpenFile(name string, flag int, perm uint32) (file *File, err Error)func Open(name string) (file *File, err Error)func Create(name string) (file *File, err Error)根據(jù)提供的文件名創(chuàng)建新的文件,返回一個文件
42、對象,默認(rèn)權(quán)限是 0666 的文件,返回的文件對象是可讀寫的。fmt.Printf(%vn, strings.HasPrefix(World Cup.png, world)/運行結(jié)果:false關(guān)閉文件函數(shù):寫文件讀文件刪除文件練習(xí):大文件拷貝示例代碼:package mainimport (fmtioos)func main() args := os.Args /獲取命令行參數(shù), 并判斷輸入是否合法if args = nil | len(args) != 3 fmt.Println(useage : xxx srcFile dstFile) returnfunc Remove(name st
43、ring) Error調(diào)用該函數(shù)就可以刪除文件名為 name 的文件func (file *File) Read(b byte) (n int, err Error)讀取數(shù)據(jù)到 b 中func (file *File) ReadAt(b byte, off int64) (n int, err Error)從 off 開始讀取數(shù)據(jù)到 b 中func (file *File) Write(b byte) (n int, err Error)寫入 byte 類型的信息到文件func (file *File) WriteAt(b byte, off int64) (n int, err Error)
44、在指定位置開始寫入 byte 類型的信息func (file *File) WriteString(s string) (ret int, err Error)寫入 string 信息到文件func (f *File) Close() errorsrcPath := args1 /獲取參數(shù) 1 dstPath := args2 /獲取參數(shù) 2fmt.Printf(srcPath = %s, dstPath = %sn, srcPath,dstPath)if srcPath = dstPath fmt.Println(error:源文件名 與 目的文件名雷同)returnsrcFile, err
45、1 := os.Open(srcPath) / 打開源文件if err1 != nil fmt.Println(err1) returndstFile, err2 := os.Create(dstPath) /創(chuàng)建目標(biāo)文件if err2 != nil fmt.Println(err2) returnbuffor:= make(byte, 1024) /切片緩沖區(qū)/從源文件讀取內(nèi)容,n 為讀取文件內(nèi)容的長度n,iferr := srcFile.Read(buf) err != nil & err != io.EOFfmt.Println(err)breakifn = 0 fmt.Println(
46、文件處理完畢)break/切片截取tmp := buf:n/把讀取的內(nèi)容寫入到目的文件dstFile.Write(tmp)/關(guān)閉文件srcFile.Close()dstFile.Close()目錄操作常用 API我們讀寫的文件一般存放于目錄中。因此,有時需要指定到某一個目錄下,根據(jù)目錄存儲的狀況再進(jìn)行文件的特定操作。接下來我們看看目錄的基本操作方法。打開目錄打開目錄我們也使用 OpenFile 函數(shù),但要指定不同的參數(shù)來系統(tǒng),要打開的是一個目錄文件。參數(shù) 1:name,表示要打開的目錄名稱。使用絕對路徑較多參數(shù) 2:flg,表示打開文件的讀寫模式??蛇x擇:O_RDONLY 只讀模式、O_WRO
47、NLY 只寫模式、O_RDWR 讀寫模式 參數(shù) 3:perm,表示打開權(quán)限。但對于目錄來說略有不同。通常傳 os.ModeDir。 返回值:由于是操作目錄,所以 file 是指向目錄的文件指針。error 中保存錯誤信息。讀目錄內(nèi)容這與讀文件有所不同。目錄中存放的是文件名和子目錄名。所以使用 Readdir 函數(shù)來完成。參數(shù):n,表讀取目錄的成員個數(shù)。通常傳-1,表讀取目錄所有文件對象。返回值:FileInfo 類型的切片。其內(nèi)部保存了文件名。error 中保存錯誤信息。type FileInfo interface Name() string / base name of the file
48、Size() int64 / length in bytes for regular files; system-dependent for others Mode() FileMode / file mode bits ModTime() time.Time / modification time IsDir() bool / abbreviation for Mode().IsDir() Sys() interface / underlying data source (can return nil) 得到 FileInfo 類型切片后,我們可以 range 遍歷切片元素,使用.Name(
49、)獲取文件名。使用.Size()獲取文件大小,使用.IsDir()判斷文件是目錄還是非目錄文件。如:我們可以提示用戶提供一個目錄位置,打開該目錄,查看目錄下的所有成員,并判別他們是文件還是目錄。示例代碼:func main() fmt.Println(請輸入要找尋的目錄:) var path string fmt.Scan(&path) / 獲 取 用 戶 指 定 的 目 錄 名 func (f *File) Readdir(n int) (FileInfo, error) func OpenFile(name string, flag int, perm FileMode) (*File,
50、error) 其他目錄操作 API其實,目錄也可以看成“文件”。我們通常讀寫的文件內(nèi)容是可見的 ASCII 碼。目錄文件的內(nèi)容就是文件名和目錄名,稱之為目錄項。我們讀寫目錄文件,實質(zhì)上就是在讀寫目錄項。目錄操作還有其他的一系列 API,這里簡單羅列幾個較為常用的,大家可自行酌情學(xué)習(xí)。將當(dāng)前工作目錄修改為 dir 指定的目錄:返回當(dāng)前工作目錄的絕對路徑:使用指定的權(quán)限和名稱創(chuàng)建一個目錄:獲取更多文件、目錄操作 API 可查看 Go 標(biāo)庫文檔: /pkgdoc文件/目錄操作練習(xí):初級練習(xí):指定目錄檢索特定文件:從用戶給出的目錄中,找出所有的 .jpg 文件。中級練習(xí):指定目錄拷貝特定文件:從用戶給出的目錄中,拷貝 .mp3 文件到指定目錄中。func Mkdir(name string, perm FileMode) errorfunc Getwd() (dir string, err error)func Chdir(di
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年能源管理與企業(yè)節(jié)能策略
- 第2單元雙休必讀經(jīng)典書
- 2026年劇本殺運營公司質(zhì)量問題整改管理制度
- 2026年劇本殺運營公司員工跨部門培訓(xùn)管理制度
- 生成式人工智能在初中歷史課堂個性化教學(xué)中的應(yīng)用探討教學(xué)研究課題報告
- 高中生對基因編輯技術(shù)科學(xué)證據(jù)的批判性思維訓(xùn)練課題報告教學(xué)研究課題報告
- 護(hù)理部護(hù)理工作信息化建設(shè)匯報
- 健全消防安全制度
- 體育消費券制度
- 會員管理制度
- 2025中國機械工業(yè)集團有限公司國機集團總部社會招聘19人筆試參考題庫附帶答案詳解
- 城鎮(zhèn)老舊供水管網(wǎng)及附屬設(shè)施升級改造工程節(jié)能評估報告
- 紀(jì)委監(jiān)委辦案安全課件
- 2026年全國婦聯(lián)所屬在京事業(yè)單位公開招聘備考題庫含答案詳解
- 2025年輸血知識考試試題及答案
- 2025-2026學(xué)年人教版八年級上冊道德與法治期末試卷(含答案和解析)
- 幼兒園消防安全管理細(xì)則解讀
- 沈陽市2025遼寧沈陽市于洪區(qū)社區(qū)殘疾人工作專職干事招聘筆試歷年參考題庫典型考點附帶答案詳解(3卷合一)
- 2026年內(nèi)蒙古電子信息職業(yè)技術(shù)學(xué)院單招職業(yè)適應(yīng)性測試題庫附答案詳解
- 2025年綿陽市中考英語試題(附答案)
- T-CASEI 026-2023 在役立式圓筒形鋼制焊接儲罐安全附件檢驗技術(shù)標(biāo)準(zhǔn)
評論
0/150
提交評論