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 /*
6 */
7
8 package main
9
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 /*
6 */
7
8 package main
9
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.统计单词出现的频率;
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 /*
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 ProgramGolang lessonDay4单词.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 /*
6 */
7
8 package main
9
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 /*
6 */
7
8 package main
9
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 /*
6 */
7
8 package main
9
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 /*
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("您输入的是:%sn",line)
35 fmt.Sscan(line,&s,&n) //将s和n的值传给line,如果不传值的话就
36 if s == "stop" {
37 break
38 }
39 fmt.Printf("您输入的第一个参数是:·033[31;1m%v033[0m·,输入的第二个参数是··033[31;1m%v033[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 /*
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 ProgramGolang lessonDay4a.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 /*
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 ProgramGolang lessonDay4b.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]#