GO語言的進階之路-Golang高級數據結構定義


                      GO語言的進階之路-Golang高級數據結構定義

                                              作者:尹正傑

版權聲明:原創作品,謝絕轉載!否則將追究法律責任。

 

  我們之前學習過Golang的基本數據類型,字符串和byte,以及rune也有所了解,但是說起高級點的數據類型,可能我們還是不太清楚,那么今天就跟着我腳步一起學習一下這些高級數據類型數據吧。相信有部分人可能學習過Python,那么我這篇博客基本上不用看了,因為對你來說會覺得so easy。因為太多的相似之處了,只是寫法不同。本章主要介紹數組(array),切片(scice),字典(map),結構體(struct)等等。

 

一.數組

  有可能你學習過shell或是python,其實從輸出的角度上來說,兩者區別不大,但是Golang的數組那是別有一番風味啊,首先在學習數組之前,你要了解數組的兩個參數重要參數,一個是數組的長度,一個是數組的容量。只要你明白了golang語言中數組這兩個性質,那么在定義的數組時你就會跳過一些坑。比如說你想把容量為3的數組賦值給容量為10的數組,是不可行的,因為容量為三的數組,其長度是3,容量為10的數組,其長度是10,(如果你想把一個數組賦值給另一個數組,首先要讓數組的長度相等,其次兩邊的類型要一致)數組的長度是類型的一部分,所以容量為3的數組是無法賦值給容量為10的數組,就是因為其長度不同,當然你也可以說是類型不同導致。

  最后我要強調的是在Golang定義一個數組后,這個數組的容量是沒法改變的。

 

1.定義一個數組並循環看其初值; 

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     var num [3]int //表示定義一個容量為3的數組,如果沒有賦初值的話默認就是"0".
14     fmt.Printf("該數組的第一個數字是:%d\n",num[0])
15     fmt.Printf("該數組的最后一個數字是:%d\n",num[len(num)-1])
16     for i,v := range num {
17         fmt.Printf("數組的下標是:%d,數組的下標對應的初值是: %d\n",i,v)
18     }
19     for _,v := range num {
20         fmt.Printf("數組的初值是:%d\n",v)
21     }
22 }
23 
24 
25 
26 #以上代碼執行結果如下:
27 該數組的第一個數字是:0
28 該數組的最后一個數字是:0
29 數組的下標是:0,數組的下標對應的初值是: 0
30 數組的下標是:1,數組的下標對應的初值是: 0
31 數組的下標是:2,數組的下標對應的初值是: 0
32 數組的初值是:0
33 數組的初值是:0
34 數組的初值是:0

 

2.數組的花式定義和賦值

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     var   num [5]int  //先定義一個容量為5的數組num。
14     num = [5]int{1,3,5,7,9} //給這num數組賦值
15     fmt.Printf("num數組的元素是:%d\n\n",num)
16 
17     var   a [3]int = [3]int{1,2,3} //將一個容量為三長度也為3的數組賦值給另一個容量為三的數組.
18     fmt.Printf("a數組的元素是:%d\n",a)
19     fmt.Printf("a[1]所對應的值是:%d\n",a[1]) //表示取a數組下標對應是1的value.
20     fmt.Printf("a數組的容量是:%d,該容量的長度是:%d,還可以存取%d個成員\n\n",cap(a),len(a),(cap(a)-len(a))) //cap函數用於計算數組的容量,len函數用於計算數組的長度.
21 
22 
23     b := [...]int{1,2,3,4} //這種定義方式其實就是不寫具體的容量參數,那么容量的值就和長度是相等的。
24     fmt.Printf("b數組的元素是:%d\n",b)
25     fmt.Printf("該數組的容量是:%d,該容量的長度是:%d,還可以存取%d個成員\n\n",cap(b),len(b),(cap(b)-len(b)))
26 
27     c := [...]int{4:20,7:-1}  //定義下標為4的值為20,下標為7的值為-1。給指定數組下標賦初值,數組的長度為最大下標的加1,如果一個數組沒有寫明容量的話,會根據其下標最大的元素來定義其容量和長度。
28     fmt.Printf("c數組的元素是:%d\n",c)
29     fmt.Printf("該數組的容量是:%d,該容量的長度是:%d,還可以存取%d個成員\n\n",cap(c),len(c),(cap(c)-len(c)))
30 }
31 
32 
33 #以上代碼執行結果如下:
34 num數組的元素是:[1 3 5 7 9]
35 
36 a數組的元素是:[1 2 3]
37 a[1]所對應的值是:2
38 a數組的容量是:3,該容量的長度是:3,還可以存取0個成員
39 
40 b數組的元素是:[1 2 3 4]
41 該數組的容量是:4,該容量的長度是:4,還可以存取0個成員
42 
43 c數組的元素是:[0 0 0 0 20 0 0 -1]
44 該數組的容量是:8,該容量的長度是:8,還可以存取0個成員

 

 3.數組的內存大小以及內存地址的查看;

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import (
11     "fmt"
12     "unsafe"
13 )
14 
15 func main()  {
16     array1 := [4]int{1,2,3} //定義array2這個數組,開辟了一款內存。
17     fmt.Printf("array1的元素是:%d\n",array1)
18     fmt.Printf("array1數組所占內存是:%d bytes\n",unsafe.Sizeof(array1)) //一個數組占有8個字節,容量為4的數組其內存是就是32字節
19     var  array2 [4]int  //定義一個
20     array2 = array1
21     fmt.Printf("array1的地址是:%d\narray2的地址是:%d\n",&array1[0],&array2[0])
22 
23     var  n1,n2 int
24     n1 = 100
25     n2 = n1  //定義的n1和n2都是單獨的容器,他們的內存地址是不一樣的喲!
26     fmt.Printf("n1的內存地址是:%d\nn2的內存地址是:%d\n",&n1,&n2)  //打印n1和n2的內存地址
27 
28     fmt.Println(n2)
29     fmt.Println(n1 == n2) //這是判斷兩個變量對應的值是否相同!如果是就為真(true),是否不是九尾假(false)
30 }
31 
32 
33 #以上代碼輸出結果如下:
34 array1的元素是:[1 2 3 0]
35 array1數組所占內存是:32 bytes
36 array1的地址是:825741296640
37 array2的地址是:825741296768
38 n1的內存地址是:825741271528
39 n2的內存地址是:825741271536
40 100
41 false

 

4.字節數組

  其實我們在之前就用過關於數組的東西,比如字節數組“[]byte”,其實它就是一個數組

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import (
11     "crypto/md5"
12     "fmt"
13 )
14 
15 func main()  {
16     data := []byte("yinzhengjie")  //定義一個byte數組.
17     md5sum := md5.Sum(data) //調用Golang的md5算法將字節數組換算成一個唯一的md5值用於文件校驗。
18     fmt.Printf("%x\n",md5sum) //打印其的md5值
19     fmt.Printf("%x\n",255) //一個十六進制的數字的取之范圍是"00-FF",所以2個16進制表示一個字符。md5就是由十六進制的數字組成的。
20 }
21 
22 
23 
24 #以上代碼執行結果如下:
25 a1424987f80af77e96f540ccda1e68e5
26 ff

 

5.數組的應用

 1 [root@yinzhengjie ~]# more md5.go 
 2 /*
 3 #!/usr/bin/env gorun
 4 @author :yinzhengjie
 5 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 6 EMAIL:y1053419035@qq.com
 7 */
 8 
 9 
10 
11 package main
12 
13 import (
14         "io/ioutil"
15         "fmt"
16         "os"
17         "crypto/md5"
18 )
19 
20 func main() {
21         var s string
22         for i := 1; i < len(os.Args); i++ {
23                 s = os.Args[i]
24                 printFile(s)
25         }
26 }
27 
28 func printFile(name string) {
29         buf, err := ioutil.ReadFile(name) //讀取文件的內容傳給buf,當然它接受到的數據時仍然是字節,即[]uint8.
30         if err != nil {
31                 fmt.Println(err)
32                 return
33         }
34         md5sum := md5.Sum(buf) //把字節buf的值用md5算法算出其md5值。
35         fmt.Printf("經計算,文件'%v'的MD5值是:%x\n",os.Args[1],md5sum)
36 }
37 [root@yinzhengjie ~]# 
38 [root@yinzhengjie ~]# go run md5.go startup.cfg 
39 經計算,文件'startup.cfg'的MD5值是:c577d25cb647991e2b44e12c67649fcc
40 [root@yinzhengjie ~]# 

 

二.切片

   Golang的切片長得和數組很像,我們可以對一個數組做切片。要注意的是:當我們對一個數組做切片的時候,如果我們修改了切片下標所對應的值,那么被切片的數組的值也會跟着改變,因為他們都指向了同一塊內存地址。

 

1.對數組做切片操作;

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import (
11     "fmt"
12 )
13 
14 func main()  {
15     primes := [8]int{2,3,5,7,9,11,13,15,} //定義一個數組
16     fmt.Printf("`primes`數組的值:%d\n",primes)
17     var  sum []int = primes[1:4]   //定義一個切片
18     fmt.Printf("`sum`切片的值:%d\n",sum)
19     fmt.Printf("`sum[0]`所對應的內存地址是:%x\n",&sum[0])
20     fmt.Printf("`primes[1]`所對應的內存地址是:%x\n",&primes[1])
21     var  s1 []int
22     s1 = sum
23     fmt.Printf("`s1`切片對應的值為:%d\n",s1)
24     fmt.Printf("s1[0] == sum[0]為:%v\n",&s1[0] == &sum[0])
25 }
26 
27 
28 
29 #以上代碼輸出結果如下:
30 `primes`數組的值:[2 3 5 7 9 11 13 15]
31 `sum`切片的值:[3 5 7]
32 `sum[0]`所對應的內存地址是:c042046088
33 `primes[1]`所對應的內存地址是:c042046088
34 `s1`切片對應的值為:[3 5 7]
35 s1[0] == sum[0]為:true

 

2.切片的原理;

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     names := [4]string{ //定義了一個字符串數組
14         "尹正傑",
15         "百度",
16         "谷歌",
17         "翻牆",
18     }
19     fmt.Println(names)
20 
21     a := names[0:2]
22     b := names[1:3]
23     fmt.Println(a,b)
24 
25     b[0] = "xxx" //修改b的元素,會將names的對應的地址做相應的修改。
26     fmt.Println(a,b)
27     fmt.Println(names)
28 }
29 
30 
31 #以上代碼輸出結果如下:
32 [尹正傑 百度 谷歌 翻牆]
33 [尹正傑 百度] [百度 谷歌]
34 [尹正傑 xxx] [xxx 谷歌]
35 [尹正傑 xxx 谷歌 翻牆]

 

3.切片的字面量

  嗨,可能你有可能聽不懂“字面量”,好吧,其實它就是對切片做初始化賦值,僅此而已!

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     num := []int{100,200,300,400,500}   //切片的初始化方法,專業術語叫做切片字面量。
14     fmt.Println(num)
15 
16     r := []bool{true,false,true,true}
17     fmt.Println(r)
18 }
19 
20 
21 
22 #以上代碼輸出結果如下:
23 [100 200 300 400 500]
24 [true false true true]

 

 

4.切片的花式玩法;

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     num := []int{2,3,5,7,9,11,13}  //定義一個切片
14     fmt.Println(num)
15     num = num[1:4] //第一次對切片做切片操作,取值結果為:[3 5 7]
16     fmt.Println(num)
17     num = num[:2] //第二次切了又切,取值結果為[3 5]
18     fmt.Println(num)
19     num = num[1:] //第三次是在第二次切片操作后又一次切片操作,取值結果為[5]
20     fmt.Println(num)
21 }
22 
23 
24 
25 #以上操作結果如下:
26 [2 3 5 7 9 11 13]
27 [3 5 7]
28 [3 5]
29 [5]

 

5.空切片;

  切片包括2個屬性,即長度和容量.因此我們不能看兩個切片的長度為0就說這2個變量是相等的。
 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     num := []int{1,2,3}  //定義一個切片
14     var s []int //定義一個空切片
15     fmt.Printf("`s`的值為:%v;長度為:%d;容量為%d\n",s,len(s),cap(s))
16     if s == nil {
17         fmt.Printf("s為空\n")
18     }
19     s1 := num[:0] //將切片num的值賦值給s1.
20     fmt.Printf("`s1`的值為:%v;長度為:%d;容量為%d\n",s1,len(s1),cap(s1))
21     fmt.Println(s1 == nil)  //雖然s1的值為[],長度為0,但是容量為3,因此該切片不是空切片!切片包括2個屬性,即長度和容量。
22 }
23 
24 
25 
26 #以上代碼輸出結果如下:
27 `s`的值為:[];長度為:0;容量為0
28 s為空
29 `s1`的值為:[];長度為:0;容量為3
30 false

 

6.切片的追加操作

  切片和數組不同,數組沒有網容器里添加元素的方法,但是切片可以的。也就是說,只要切片的容量固定,我們可以根據容量大小往里添加數據相應的元素。

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     var s []int //定義一個空切片s.
14     s = []int{1,2,3} //給這個空切片s賦值.
15     slice_attribute(s)
16     s = append(s,0) //往切片s追加一個"0"元素。
17     slice_attribute(s)
18     s = append(s,2,3,4) //繼續往切片s追加“2,3,4”等元素。
19     slice_attribute(s)
20 
21 }
22 
23 func slice_attribute(s []int)  {
24     fmt.Printf("len=%d cap=%d %v\n",len(s),cap(s),s)  //打印切片的長度,容量以及對應的value.
25 }
26 
27 
28 
29 
30 #以上代碼輸出結果如下:
31 len=3 cap=3 [1 2 3]
32 len=4 cap=6 [1 2 3 0]
33 len=7 cap=12 [1 2 3 0 2 3 4]

 

7.用make函數定義一個切片;

  make函數不僅僅可以定義一個切片,還可以定義一個map(你可以理解成字典)。

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     slice1 := make([]int,5)  //表示定義一個長度為5的切片
14     my_slice("slice1",slice1)
15     slice2 := make([]int,0,5) //表示定義一個長度為0,容量為5的切片
16     my_slice("slice2",slice2)
17     slice3 := slice2[:2]
18     my_slice("slice3",slice3)
19     slice4 := slice3[2:5]
20     my_slice("slice4",slice4)
21 }
22 
23 func my_slice(s string ,x []int)  {
24     fmt.Printf("`%s`切片長度為:%d 切片容量為:%d 切片中的元素是:%v\n",s,len(x),cap(x),x)
25 }
26 
27 
28 #以上代碼執行結果如下:
29 `slice1`切片長度為:5 切片容量為:5 切片中的元素是:[0 0 0 0 0]
30 `slice2`切片長度為:0 切片容量為:5 切片中的元素是:[]
31 `slice3`切片長度為:2 切片容量為:5 切片中的元素是:[0 0]
32 `slice4`切片長度為:3 切片容量為:3 切片中的元素是:[0 0 0]

 

 

8.小試牛刀;

  好了,關於切片的基本上這些就夠用了,我們可以來小試牛刀一下啦~看看你掌握了多少;

A.反轉切片的值;

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     var   num []int
14     num = []int{1,3,5,7}
15     fmt.Printf("切片反轉之前的順序是:%d\n",num)
16     my_rerversal(num)
17     fmt.Printf("切片反轉之后的順序是:%d\n",num)
18     }
19 
20 func my_rerversal(s []int) {  //該函數用於反轉
21     for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
22         s[i], s[j] = s[j], s[i]
23     }
24 }
25 
26 
27 #以上代碼執行結果如下:
28 切片反轉之前的順序是:[1 3 5 7]
29 切片反轉之后的順序是:[7 5 3 1]

 

B.隨機反轉切片的值;

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 
 9 package main
10 
11 import (
12     "bufio"
13     "os"
14     "fmt"
15 
16     "strconv"
17 )
18 
19 var   (
20     s string
21     line string
22 )
23 func main()  {
24     f := bufio.NewReader(os.Stdin)
25     num := []int{100,200,300,400,500,600,700,800}
26     fmt.Printf("現有一些數字:·\033[32;1m%v\033[0m·\n",num)
27     for {
28         fmt.Print("請您想要反轉下標的起始的位置>")
29         line,_ = f.ReadString('\n')
30         if len(line) == 1 {
31             continue  //過濾掉空格;
32         }
33         fmt.Sscan(line,&s)
34         if s == "stop" {
35             break //定義停止程序的鍵值;
36         }
37         index,err := strconv.Atoi(s)
38         if err != nil {
39             fmt.Println("對不起,您必須輸入一個數字")
40         }
41         num1 := num[:index]
42         num2 := num[index:]
43         i := 0
44         for {
45 
46             num2=append(num2, num1[i])
47             i = i + 1
48             if i >= len(num1) {
49                 break
50             }
51         }
52         fmt.Printf("反轉后的內容是·\033[31;1m%v\033[0m·\n",num2)
53     }
54 }
55 
56 
57 
58 #以上代碼輸出結果如下:
59 現有一些數字:·[100 200 300 400 500 600 700 80060 請您想要反轉下標的起始的位置>1
61 反轉后的內容是·[200 300 400 500 600 700 800 10062 請您想要反轉下標的起始的位置>3
63 反轉后的內容是·[400 500 600 700 800 100 200 30064 請您想要反轉下標的起始的位置>5
65 反轉后的內容是·[600 700 800 100 200 300 400 50066 請您想要反轉下標的起始的位置>7
67 反轉后的內容是·[800 100 200 300 400 500 600 70068 請您想要反轉下標的起始的位置>
69 請您想要反轉下標的起始的位置>
70 請您想要反轉下標的起始的位置>2
71 反轉后的內容是·[300 400 500 600 700 800 100 20072 請您想要反轉下標的起始的位置>4
73 反轉后的內容是·[500 600 700 800 100 200 300 40074 請您想要反轉下標的起始的位置>6
75 反轉后的內容是·[700 800 100 200 300 400 500 60076 請您想要反轉下標的起始的位置>8
77 反轉后的內容是·[100 200 300 400 500 600 700 80078 請您想要反轉下標的起始的位置>
79 請您想要反轉下標的起始的位置>

C.單詞反轉;

   想要實現單詞反轉,有個package你必須虛得了解,那就是strings包。只要你知道這個packge基本上就能搞定這個事情啦!

hello world Golang! 尹正傑
你好.txt
 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import (
11     "io/ioutil"
12     "log"
13     "fmt"
14     "strings"
15 )
16 
17 func main() {
18     buf, err := ioutil.ReadFile("D:\\Golang環境\\Golang Program\\Golang lesson\\Day4\\你好.txt")
19     if err != nil {
20         log.Fatal(err)
21     }
22     fmt.Println(string(buf))
23     str := strings.Fields(string(buf))
24     my_rerversal(str)
25 
26 }
27 
28 
29 func my_rerversal(s []string) {
30     for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
31         s[i], s[j] = s[j], s[i]
32     }
33     str1 := strings.Join(s," ") //把切片轉換成字符串。
34     str1 = str1
35     fmt.Println(str1)
36 }
37 
38 
39 
40 #以上代碼執行結果如下:
41 hello world Golang! 尹正傑
42 尹正傑 Golang! world hello

 

 

 

 

三.map(你可以理解為字典。)

   可能大家剛剛接觸Golang的小伙伴都會跟我一樣,這個map是干嘛的,是函數嗎?學過python的小伙伴可能會想到map這個函數。其實它就是Golang中的字典。下面跟我一起看看它的特性吧。

  A.hash方式的;

  B.無序的;

  C.0(1)的訪問時間;

  擴充: (n):存n個元素就需要轉n圈目的數據;

        0(n^2):存n個元素就需要n的平方圈目的數據;

        0(2^n):存n個元素就需要2的n次方圈才能訪問到目的數據;

        0(1):不管存多少個元素,只轉一圈就能找到(其實就是類似與python中的字典,有專用的key綁定一個value值。);

            0(logn):排序查找,比入10000個元素中我們想要查數字10,那么可能只要查10次就查出來來;

 

 1.定義一個map;

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     info := make(map[string]int) //定義一個空字典,其key的數據類型是字符串,其value對應的數據是數字
14     info["age"] = 25 //往空字典中傳值
15     info["size"] = 18
16     fmt.Println(info["age"])  //查看key所對應的value.
17     info["age"] = info["size"] + 100 //其實是數字相加運算
18     fmt.Println(info["age"])
19     info2 := map[string]string{
20         "name" : "尹正傑",
21         "age"  : "25",
22     }
23 
24     c,ok := info2["c"] //判斷key是否在info2中
25     if ok {
26         fmt.Println(c)
27     }else {
28         fmt.Println("真不好意思,你所說的key在我的字典里壓根不存在!")
29     }
30     fmt.Println(info2)
31 
32     if hight,ok := info["d"];ok { //判斷key是否在info中
33         fmt.Println(hight)
34     }else {
35         info["hight"] = 111
36     }
37     fmt.Println(info)
38 }
39 
40 
41 
42 #以上代碼執行結果如下:
43 25
44 118
45 真不好意思,你所說的key在我的字典里壓根不存在!
46 map[name:尹正傑 age:25]
47 map[age:118 size:18 hight:111]

 

2.刪除一個map;

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     dict:= map[string]int{
14         "a" :1,
15     }
16     fmt.Println(dict)
17     delete(dict,"a")  //刪除map中key所對應的value.
18     fmt.Println(dict)
19 
20     var dict_1  map[string]int
21     fmt.Println(dict_1 == nil) //定義了一個空字典,內容為空
22     fmt.Println(dict_1)
23     dict_1 = make(map[string]int) //如果m1等於空(nil),需要重新m1才能用m1,不能直接對其賦值
24     dict_1["c"]=100
25     fmt.Println(dict_1)
26 }
27 
28 
29 
30 #以上代碼執行結果如下:
31 map[a:1]
32 map[]
33 true
34 map[]
35 map[c:100]

 

3.遍歷map;

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main()  {
13     ages := map[string]string{
14         "姓名":"尹正傑",
15         "年齡":"25",
16     }
17     for i,j := range ages { //遍歷key和value。
18         fmt.Println("key=",i,"value=",j)
19     }
20 
21     for i := range ages { //只遍歷key.
22         fmt.Println(i)
23     }
24 }
25 
26 
27 #以上代碼執行結果如下:
28 key= 姓名 value= 尹正傑
29 key= 年齡 value= 25
30 姓名
31 年齡

 

4.小試牛刀;

A.定義一個集合的思想;

  學過Python的同學,可能聽說過集合,但是我要告訴你一個好消息和一個壞消息,你想先聽哪一個?

  壞消息就是Golang沒有集合這個概念;好消息是我們可以用Golang的make函數來實現集合的思想,下面跟我一起看個例子吧!

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 func main() {
13     set := make(map[string]bool) //定義一個map
14     set["a"] = true              //給已經存在的變量定義為真
15     if set["a"] {
16         fmt.Println("已經存在該變量")
17 
18     } else {
19         fmt.Println("該變量不存在!")
20     }
21 
22     if set["b"] {
23         fmt.Println("已經存在該變量")
24 
25     } else {
26         fmt.Println("該變量不存在!")
27 
28     }
29 }
30 
31 
32 
33 #以上代碼執行結果如下:
34 已經存在該變量
35 該變量不存在!

 

B.統計單詞出現的頻率;

   Scanner provides a convenient interface for reading data such as a file of newline-delimited lines of text Successive
calls to the Scan method will step through the tokens of a file skipping the bytes between the tokens The specification
of a token is defined by a split function of type SplitFunc the default split function breaks the input into lines with
line termination stripped Split functions are defined in this package for scanning a file into lines bytes UTF-8-encoded
runes and space-delimited words The client may instead provide a custom split function
單詞.txt
  1 /*
  2 #!/usr/bin/env gorun
  3 @author :yinzhengjie
  4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  5 EMAIL:y1053419035@qq.com
  6 */
  7 
  8 package main
  9 
 10 import (
 11     "fmt"
 12     "io/ioutil"
 13     "log"
 14     "strings"
 15 )
 16 
 17 func main()  {
 18     buf,err := ioutil.ReadFile("D:\\Golang環境\\Golang Program\\Golang lesson\\Day4\\單詞.txt")
 19     if err != nil {
 20         log.Fatal(err)
 21     }
 22     statistic_times := make(map[string]int)
 23     words_length := strings.Fields(string(buf))
 24 
 25     for counts,word := range words_length {
 26         word,ok :=statistic_times[word]  //判斷key是否存在,這個word是字符串,這個counts是統計的word的次數。
 27         if ok{
 28             word = word //我這里是重新賦值,因為上面定義了,下面必須用這個變量,不然就報錯,有大神可以幫忙優化一下這里。
 29             statistic_times[words_length[counts]] = statistic_times[words_length[counts]] + 1
 30         }else {
 31             statistic_times[words_length[counts]] = 1
 32         }
 33     }
 34     for word,counts := range statistic_times {
 35         fmt.Println(word,counts)
 36     }
 37 }
 38 
 39 
 40 
 41 #以上代碼輸出結果如下:
 42 
 43 lines 3
 44 method 1
 45 functions 1
 46 in 1
 47 words 1
 48 may 1
 49 newline-delimited 1
 50 the 6
 51 package 1
 52 provides 1
 53 will 1
 54 step 1
 55 through 1
 56 skipping 1
 57 stripped 1
 58 Scanner 1
 59 as 1
 60 tokens 2
 61 specification 1
 62 space-delimited 1
 63 client 1
 64 function 3
 65 instead 1
 66 for 2
 67 of 5
 68 by 1
 69 termination 1
 70 interface 1
 71 between 1
 72 breaks 1
 73 with 1
 74 line 1
 75 runes 1
 76 Successive 1
 77 SplitFunc 1
 78 into 2
 79 Split 1
 80 reading 1
 81 defined 2
 82 type 1
 83 default 1
 84 input 1
 85 custom 1
 86 text 1
 87 to 1
 88 Scan 1
 89 bytes 2
 90 is 1
 91 such 1
 92 token 1
 93 are 1
 94 file 3
 95 The 2
 96 split 3
 97 UTF-8-encoded 1
 98 and 1
 99 provide 1
100 a 7
101 convenient 1
102 data 1
103 calls 1
104 this 1
105 scanning 1

 

 四.struct(結構體);

  說道結構體,大家可能會懵逼,不知道是個啥東西,其實我覺得Golang起的結構體這個名字還是蠻接地氣的,不是嗎?從字面意思就可以理解為一個數據的結構體系。基本上一聽這個名字就大致知道是干嘛的,它就好似一個模板,讓我們看清楚了她的各個主要分支結構。其實,在Python中,我們叫它實例,說白了,當初學習Python實例的和實例化的時候讓我很懵逼,隨着時間的推移我才明白什么是實例,什么是實例化。相信學習過Python的同學應該都知道class。其實結構體,我們就可以理解成Python中的定義一個實例,而用這個結構體的時候,我們就可以理解是在實例化這個對象。

 

1.定義一個結構體以及實例化結構體的兩種方式;

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 type Student struct { //定義一個結構體,類似與python定義的一個實例
13     ID int
14     Name string
15 }
16 
17 func main()  {
18     var  s Student //引用結構體,方式一。【可以理解為實例化】
19     s.ID = 100
20     s.Name = "yinzhengjie"
21     fmt.Println(s)
22 
23     s1 := Student{ //引用結構體,方式二
24         ID:200,
25         Name:"餅干",
26     }
27     fmt.Println(s1)
28 }
29 
30 
31 #以上代碼輸出結果如下:
32 {100 yinzhengjie}
33 {200 餅干}

 

2.結構體的指針;

   在Golang的全局變量中,我們聲明一個變量的同時,還需要制定其數據類型,可以是int,string,byte,也可以是[]int,[]string,[]byte,還可以是我們自定義的結構體等等。

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 type Student struct { //定義一個結構體
13     ID int
14     Name string
15 }
16 
17 func main()  {
18 
19     s1 := Student{  //引用(實例化)結構體
20         ID:100,
21         Name:"尹正傑",
22     }
23     fmt.Println(s1)
24 
25     var   p *Student  //定義p為我們自定義的結構體類型
26     p = &s1  //將實例化的內存地址傳給p
27     p.ID = 200 //修改結構體里面的ID參數為200,由於p是指針類型,故會修改s1的ID的值。
28     fmt.Println(s1)
29 
30     var p1 *int
31     p1 = &s1.ID //我們也可以直接取到我們自定義的結構體重的參數的內存地址,然后給其賦值,也能達到修改參數的效果。
32     *p1 = 300
33     fmt.Println(s1)
34 }
35 
36 
37 #以上代碼輸出結果如下:
38 {100 尹正傑}
39 {200 尹正傑}
40 {300 尹正傑}

 

五.交互模式

  一般用Golang寫的運維工具都是自己把功能跑完,不需要每次手動執行一些命令才能完成工作。但是在這幾道一些安全性信息的時候就不得不要求用戶交互了,比如你登錄QQ,登錄你的愛奇藝會員,騰訊會員以及樂視會員等等。都需要你手動輸入一些字符串。那么問題來了,Golang是如何實現這功能的呢?跟着我一起實驗吧! 

 

1.初探交互模式;

  我們寫一個交互程序,讓用戶輸入什么就打印出來什么。

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import "fmt"
11 
12 
13 var cmd string
14 
15 func main()  {
16     for { //循環輸入
17         fmt.Print("input>>")  //輸入的內容都是字符串類型。
18         fmt.Scan(&cmd) //獲取用命令行中第一字符串傳給cmd。
19         if cmd == "stop" {  //定義結束循環的關鍵字
20             break
21         }
22         fmt.Println(cmd) //將輸入的字符串cmd變量打印出來
23     }
24 }
25 
26 
27 #以上代碼執行結果如下:
28 input>>尹正傑
29 尹正傑
30 input>>yinzhengjie
31 yinzhengjie
32 input>>您好
33 您好
34 input>>hello
35 hello
36 input>>world
37 world
38 input>>

 

2.獲取一整行內容;

  獲取通過第一個交互模式你也體會到了,存在很多坑,比如不能把輸出空格或者回車就會卡在那里不動了,無法獲取完整的一行內容並打印,只能講命令行的第一個位置參數給打印出來,那么如果將一整行的內容都打印出來呢?這個時候我們就需要對bufio這個package需要一定的掌握。

 

 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 
 9 package main
10 
11 import (
12 "bufio"
13 "os"
14 "fmt"
15     "strings"
16 )
17 
18 var   (
19     s string
20     n int
21     line string
22 )
23 func main()  {
24     f := bufio.NewReader(os.Stdin) //讀取輸入的內容
25     for {
26         fmt.Print("請輸入一些字符串>")
27         line,_ = f.ReadString('\n') //定義一行輸入的內容分隔符。
28         if len(line) == 1 {
29             continue //如果用戶輸入的是一個空行就讓用戶繼續輸入。
30         }
31         line = strings.Replace(line,"\n"," ",-1)  //利用string的修改操作,將換行符脫掉。
32         // 要注意的是它是需要單獨占用內存的。其實這行沒必要寫,因為只需要把下一行的“\n”去掉就好使啦
33         // 即:fmt.Printf("您輸入的是:%s",line),因為我剛剛學的時候踩了個坑,所以在這里記錄下。
34         fmt.Printf("您輸入的是:%s\n",line)
35         fmt.Sscan(line,&s,&n) //將s和n的值傳給line,如果不傳值的話就
36         if s == "stop" {
37             break
38         }
39         fmt.Printf("您輸入的第一個參數是:·\033[31;1m%v\033[0m·,輸入的第二個參數是··\033[31;1m%v\033[0m·.\n",s,n)
40     }
41 }
42 
43 
44 
45 #意思代碼輸出結果如下:
46 請輸入一些字符串>
47 請輸入一些字符串>
48 請輸入一些字符串>GOLANG 123
49 您輸入的是:GOLANG 123 
50 您輸入的第一個參數是:·GOLANG·,輸入的第二個參數是··123·.
51 請輸入一些字符串>

 

 

 六.序列化和反序列化(json)

   說直白點,序列化就是講數據寫入硬盤,反序列化就是講數據從硬盤讀取出來。而存取方式又是用戶選取的一個難題,每種語言都有自己的存取數據的方式,不過很多種語言都一款通用的存取方式,那就是json。也就是說很多語言都支持這種存儲,說的在直白點就是你用Golang將數據用json存取,我可以用JAVA語言打卡這個文件內容,並獲取到文件的內容做相應的處理。

 

1.序列化案例;

   執行之前的“a.txt”文件內容

http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
a.txt執行代碼之前的內容
http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
{"ID":1,"Name":"yinzhengjie"}
a.txt執行代碼之后的內容
 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import (
11     "encoding/json"
12     "log"
13     "fmt"
14     "os"
15 )
16 
17 type Student struct {
18     ID int
19     Name string
20 }
21 
22 func main()  {
23     s := Student{
24         ID:1,
25         Name:"yinzhengjie",
26     }
27     buf,err := json.Marshal(s) //序列化一個結構體,
28     if err != nil {
29         log.Fatal("序列化報錯是:%s",err)
30     }
31     f,err := os.OpenFile("D:\\Golang環境\\Golang Program\\Golang lesson\\Day4\\a.txt",os.O_APPEND|os.O_CREATE|os.O_RDWR,0644)
32     if err    != nil {
33         log.Fatal(err)
34     }
35     f.WriteString(string(buf))
36     f.WriteString("\n")
37     f.Close()
38     fmt.Println("寫入成功")
39 }
40 
41 
42 
43 #以上代碼執行結果如下:
44 寫入成功

 

2.反序列化之前的內容;

  文件“b.txt”內容如下:

{100 yinzhengjie}
“b.txt”文件內容
 1 /*
 2 #!/usr/bin/env gorun
 3 @author :yinzhengjie
 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
 5 EMAIL:y1053419035@qq.com
 6 */
 7 
 8 package main
 9 
10 import (
11     "encoding/json"
12     "log"
13     "fmt"
14     "io/ioutil"
15 )
16 
17 type Student struct {
18     ID int
19     Name string
20 }
21 
22 func main()  {
23     buf,err := ioutil.ReadFile("D:\\Golang環境\\Golang Program\\Golang lesson\\Day4\\b.txt")
24     if err != nil {
25         fmt.Println("你愁啥?文件打開錯誤了!")
26         return
27     }
28     var str  Student
29     err1 := json.Unmarshal(buf,&str)
30     if err1 != nil {
31         log.Fatal("反序列化報錯啦:%s",err1)
32     }
33     fmt.Println(str)
34 }
35 
36 
37 #以上代碼執行結果如下:
38 {100 yinzhengjie}

 

 3.小試牛刀;

  寫一個簡單的交互學生管理系統,需要運用的知識點有:map,文件處理,序列化,字符串處理,結構體等等,以下僅是初稿,暫時提供的一個思路。

 

  1 [root@yinzhengjie tmp]# more student.go 
  2 /*
  3 #!/usr/bin/env gorun
  4 @author :yinzhengjie
  5 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
  6 EMAIL:y1053419035@qq.com
  7 */
  8 
  9 package main
 10 
 11 import (
 12         "bufio"
 13         "fmt"
 14         "os"
 15         "log"
 16         "io"
 17         "encoding/json"
 18         "strings"
 19 )
 20 
 21 var   (
 22         cmd string
 23         name string
 24         id int
 25         line string
 26         file_name string
 27 )
 28 
 29 type Student struct {
 30         ID   int
 31         Name string
 32 }
 33 
 34 func main() {
 35         f := bufio.NewReader(os.Stdin)
 36         for {
 37                 fmt.Print(" 請輸入>>> ")
 38                 line, _ = f.ReadString('\n')
 39                 fmt.Sscan(line, &cmd)
 40                 if len(line) == 1 {
 41                         continue
 42                 }
 43                 switch cmd {
 44                 case "list":
 45                         list()
 46                 case "add":
 47                         add()
 48                 case "save":
 49                         save()
 50                 case "load":
 51                         load()
 52                 case "stop":
 53                         os.Exit(0)
 54                 default:
 55                         fmt.Println("您輸出的命令無效")
 56                 }
 57         }
 58 }
 59 
 60 func list()  {
 61         f,err := os.Open("student_info.json") //打開一個文件,如果這個文件不存在的話就會報錯。
 62         if err != nil {
 63                 log.Fatal(err)
 64         }
 65         r := bufio.NewReader(f) //取出文件的內容
 66         for {
 67                 line,err := r.ReadString('\n')
 68                 if err == io.EOF{
 69                         break
 70                 }
 71                 fmt.Print(line)
 72         }
 73         f.Close()
 74 }
 75 
 76 
 77 func add() {
 78         fmt.Sscan(line, &cmd, &id, &name)
 79         f, err := os.Open("student_info.json") //打開一個文件,如果這個文件不存在的話就會報錯。
 80         if err != nil {
 81                 log.Fatal(err)
 82         }
 83         r := bufio.NewReader(f) //取出文件的內容
 84         flag := 0 //定義一個標志位,當輸入的ID和name相同時,就將其的值改為1.
 85         for {
 86                 line, err := r.ReadString('\n')
 87                 if err == io.EOF {
 88                         break
 89                 }
 90                 s := Student{
 91                         ID:   id,
 92                         Name: name,
 93                 }
 94                 buf, err := json.Marshal(s)
 95                 if err != nil {
 96                         log.Fatal("序列化報錯是:%s", err)
 97                 }
 98                 line = strings.Replace(line,"\n","",-1) //將換行符替換為空,你可以理解是刪除了換行符。
 99                 if line == string(buf) {
100                         fmt.Println("對不起,您輸入的用戶或者ID已經存在了,請重新輸入!")
101                         flag = 1
102                         break
103 
104                 }
105         }
106         if flag == 0 {
107                 s := Student{
108                         ID:id,
109                         Name:name,
110                 }
111                 buf,err := json.Marshal(s) //序列化一個結構體,
112                 if err != nil {
113                         log.Fatal("序列化報錯是:%s",err)
114                 }
115                 fmt.Println(string(buf))
116                 f,err := os.OpenFile("student_info.json",os.O_APPEND|os.O_CREATE|os.O_RDWR,0644)
117                 if err    != nil {
118                         log.Fatal(err)
119                 }
120                 f.WriteString(string(buf))
121                 f.WriteString("\n")
122                 f.Close()
123                 fmt.Println("寫入成功")
124 
125         }
126 }
127 func save()  {
128         fmt.Sscan(line, &cmd,&file_name)
129         f,err := os.Open("student_info.json") //打開一個文件,如果這個文件不存在的話就會報錯。
130         if err != nil {
131                 log.Fatal(err)
132         }
133         r := bufio.NewReader(f) //取出文件的內容
134         f2,err := os.OpenFile(file_name,os.O_APPEND|os.O_CREATE|os.O_RDWR,0644) //打開一個新文件
135         if err    != nil {
136                 log.Fatal(err)
137         }
138         for {
139                 line,err := r.ReadString('\n')
140                 if err == io.EOF{
141                         break
142                 }
143                 f2.WriteString(line) //將student_info.json內容寫到指定的文件中去。
144         }
145         f2.Close()
146         f.Close()
147 }
148 
149 func load()  {
150         fmt.Sscan(line, &cmd,&file_name)
151         f,err := os.Open(file_name) //打開一個文件,如果這個文件不存在的話就會報錯。
152         if err != nil {
153                 fmt.Println("對不起!系統沒用找到該文件!")
154                 return
155         }
156         r := bufio.NewReader(f) //取出文件的內容
157         for {
158                 line,err := r.ReadString('\n')
159                 if err == io.EOF{
160                         break
161                 }
162                 fmt.Print(line)
163         }
164         f.Close()
165 }
166 [root@yinzhengjie tmp]# 
167 [root@yinzhengjie tmp]# 
168 [root@yinzhengjie tmp]# 
169 [root@yinzhengjie tmp]# 
170 [root@yinzhengjie tmp]# go run student.go 
171  請輸入>>> 
172  請輸入>>> 
173  請輸入>>> list
174 {"ID":1,"Name":"bingan"}
175 {"ID":2,"Name":"yinzhengjie"}
176 {"ID":3,"Name":"jie"}
177 {"ID":5,"Name":"Golang"}
178 {"ID":4,"Name":"reboot"}
179 {"ID":10,"Name":"jie"}
180 {"ID":100,"Name":"dev"}
181 {"ID":200,"Name":"jay"}
182  請輸入>>> 
183  請輸入>>> 
184  請輸入>>> add 300 GOOD 
185 {"ID":300,"Name":"GOOD"}
186 寫入成功
187  請輸入>>> list
188 {"ID":1,"Name":"bingan"}
189 {"ID":2,"Name":"yinzhengjie"}
190 {"ID":3,"Name":"jie"}
191 {"ID":5,"Name":"Golang"}
192 {"ID":4,"Name":"reboot"}
193 {"ID":10,"Name":"jie"}
194 {"ID":100,"Name":"dev"}
195 {"ID":200,"Name":"jay"}
196 {"ID":300,"Name":"GOOD"}
197  請輸入>>> 
198  請輸入>>> save 6666
199  請輸入>>> 
200  請輸入>>> load 6666
201 {"ID":1,"Name":"bingan"}
202 {"ID":2,"Name":"yinzhengjie"}
203 {"ID":3,"Name":"jie"}
204 {"ID":5,"Name":"Golang"}
205 {"ID":4,"Name":"reboot"}
206 {"ID":10,"Name":"jie"}
207 {"ID":100,"Name":"dev"}
208 {"ID":200,"Name":"jay"}
209 {"ID":300,"Name":"GOOD"}
210  請輸入>>> 
211  請輸入>>> stop
212 You have new mail in /var/spool/mail/root
213 [root@yinzhengjie tmp]# 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM