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
",num[0])
15     fmt.Printf("该数组的最后一个数字是:%d
",num[len(num)-1])
16     for i,v := range num {
17         fmt.Printf("数组的下标是:%d,数组的下标对应的初值是: %d
",i,v)
18     }
19     for _,v := range num {
20         fmt.Printf("数组的初值是:%d
",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

",num)
16 
17     var   a [3]int = [3]int{1,2,3} //将一个容量为三长度也为3的数组赋值给另一个容量为三的数组.
18     fmt.Printf("a数组的元素是:%d
",a)
19     fmt.Printf("a[1]所对应的值是:%d
",a[1]) //表示取a数组下标对应是1的value.
20     fmt.Printf("a数组的容量是:%d,该容量的长度是:%d,还可以存取%d个成员

",cap(a),len(a),(cap(a)-len(a))) //cap函数用于计算数组的容量,len函数用于计算数组的长度.
21 
22 
23     b := [...]int{1,2,3,4} //这种定义方式其实就是不写具体的容量参数,那么容量的值就和长度是相等的。
24     fmt.Printf("b数组的元素是:%d
",b)
25     fmt.Printf("该数组的容量是:%d,该容量的长度是:%d,还可以存取%d个成员

",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
",c)
29     fmt.Printf("该数组的容量是:%d,该容量的长度是:%d,还可以存取%d个成员

",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
",array1)
18     fmt.Printf("array1数组所占内存是:%d bytes
",unsafe.Sizeof(array1)) //一个数组占有8个字节,容量为4的数组其内存是就是32字节
19     var  array2 [4]int  //定义一个
20     array2 = array1
21     fmt.Printf("array1的地址是:%d
array2的地址是:%d
",&array1[0],&array2[0])
22 
23     var  n1,n2 int
24     n1 = 100
25     n2 = n1  //定义的n1和n2都是单独的容器,他们的内存地址是不一样的哟!
26     fmt.Printf("n1的内存地址是:%d
n2的内存地址是:%d
",&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
",md5sum) //打印其的md5值
19     fmt.Printf("%x
",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
",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
",primes)
17     var  sum []int = primes[1:4]   //定义一个切片
18     fmt.Printf("`sum`切片的值:%d
",sum)
19     fmt.Printf("`sum[0]`所对应的内存地址是:%x
",&sum[0])
20     fmt.Printf("`primes[1]`所对应的内存地址是:%x
",&primes[1])
21     var  s1 []int
22     s1 = sum
23     fmt.Printf("`s1`切片对应的值为:%d
",s1)
24     fmt.Printf("s1[0] == sum[0]为:%v
",&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
",s,len(s),cap(s))
16     if s == nil {
17         fmt.Printf("s为空
")
18     }
19     s1 := num[:0] //将切片num的值赋值给s1.
20     fmt.Printf("`s1`的值为:%v;长度为:%d;容量为%d
",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
",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
",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
",num)
16     my_rerversal(num)
17     fmt.Printf("切片反转之后的顺序是:%d
",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("现有一些数字:·33[32;1m%v33[0m·
",num)
27     for {
28         fmt.Print("请您想要反转下标的起始的位置>")
29         line,_ = f.ReadString('
')
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("反转后的内容是·33[31;1m%v33[0m·
",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('
') //定义一行输入的内容分隔符。
28         if len(line) == 1 {
29             continue //如果用户输入的是一个空行就让用户继续输入。
30         }
31         line = strings.Replace(line,"
"," ",-1)  //利用string的修改操作,将换行符脱掉。
32         // 要注意的是它是需要单独占用内存的。其实这行没必要写,因为只需要把下一行的“
”去掉就好使啦
33         // 即:fmt.Printf("您输入的是:%s",line),因为我刚刚学的时候踩了个坑,所以在这里记录下。
34         fmt.Printf("您输入的是:%s
",line)
35         fmt.Sscan(line,&s,&n) //将s和n的值传给line,如果不传值的话就
36         if s == "stop" {
37             break
38         }
39         fmt.Printf("您输入的第一个参数是:·33[31;1m%v33[0m·,输入的第二个参数是··33[31;1m%v33[0m·.
",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("
")
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('
')
 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('
')
 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('
')
 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,"
","",-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("
")
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('
')
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('
')
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]# 

 

 

 

原文地址:https://www.cnblogs.com/yinzhengjie/p/7079626.html