zoukankan      html  css  js  c++  java
  • 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]# 

     

     

     

  • 相关阅读:
    弄明白python reduce 函数
    Python 2与Python 3兼容性的写法,需要一个特殊的包 from __future__ import print_function 用法
    人工智能数学参考---8、常用激活函数
    常用激活函数(激励函数)理解与总结
    人工智能数学参考---7、核函数应用
    [粘贴]环绕闸极不能让三星在3nm工艺领先台积电
    查看java所有的线程信息
    【转载】 Sqlserver使用Left函数从最左边开始截取固定长度字符串
    值初始化和默认初始化的区别
    map的综合例子
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/7079626.html
Copyright © 2011-2022 走看看