之前学习的go语言有些要注意的和没明白的地方在这里总结一下下,以便以后参考查阅。
一.golang的编码规范
- 源文件是使用UTF-8编码的Unicode文本
- 注释是不能嵌套的
- package包名 :小写单词,不要下划线
- 不同类型的包用空格分开,并且有顺序的引入包(实标准库,项目包,第三方包),这就是纯粹的习惯问题了
- 变量:全局变量、参数变量、局部变量都可以驼峰式
- 一行代码为结束,不要再添加“;”
- 函数大括号一定要错开书写,莫对齐
- for循环
for i :=0 ; i<size; i++{
}
i:=0代表声明定义类型,(for循环不加括号)
- Inint()函数的用法:
func init(){
fmt.Println(“输入内容!”)
}
- defer在相关函数内运行,比如在main函数里面直接输入
defer fmt.Println(“输入相关内容”)
或者:
defer func(){
fmt.Println(“ ”)
}()
在这里说明一下defer函数的作用:用来标记最后执行的go语句,(资源释放,关闭连接等操作,在函数关闭前调用)多个defer的定义与执行类似于栈的操作,先进后出,最先定义的最后在执行。
go语言中的swich case语句不再需要break语句来中断程序
new关键字主要用于结构体的初始化,而make关键字主要用于数组array、切片slice、map集合,协程管道channel的初始化
- 检测map集合中的元素是否存在:
exist,ok := m[2]
if ok{
fmt.Println(如果存在,则输出存在)
}else{
}
delete()函数作用是删除map集合中的元素,格式为
delete(map集合名,key值)
- 切片slice,又叫动态数组,与数组相比切片的长度不固定,可以追加元素,与此同时可能使切片的容量增大。(通过内置函数make()初始化切片s,[]int 标识为其元素类型为int的切片)
- 一般情况下,channel接收和发送的数据都是阻塞的,比如:<-value就表示没有接收value的channel
- 这里申明一点:
.Channel的定义:
c := make(chan string)
c = “sssdsdsds”
这样运行时会报错,出现死锁问题。
c := make(chan string,100)
其中,make的第二个参数指定缓存的大小,通过缓存的使用,可以尽量避免阻塞,提高应用的性能。
一般不带参数的管道初始化叫做同步模式,带参数的管道初始化叫做队列模式
二.编译问题
1.接口问题以及实例化对象
package main
import "fmt"
//定义包含Dinner()方法的接口
type Dinner interface {
action()
}
//定义职位的结构体
type Person struct {
name string
age int
}
//定义学生的结构体
type Student struct {
Person //继承职位的结构体内容,在这里全部可以使用
hobby string
}
//定义工人的结构体
type Worker struct {
Person //同样继承职位的结构体~
money int
}
//学生类下的实现方法定义
func (s Student) action(){
fmt.Println("happy student!",s.name,s.hobby)
}
//工人类下的实现方法定义
func (w Worker) action(){
fmt.Println("hardworking worker!",w.name,w.money)
}
func main(){
//实例化对象,显示所有声明的对象
student := Student{Person{"tony",13},"study"}
worker := Worker{Person{"大锤",34},6700}
//调用接口实现的方法,输出结果
student.action()
worker.action()
}
利用 go run main.go运行后输出结果为:
happy student! tony study
hardworking worker! 大锤 6700
Process finished with exit code 0
2.并发程序的理解
在这里自己编写了一个简单的协程并发程序,帮助理解。
go语言中, 同步进程使用sync包中的wiatgroup结构体,它实现了一个类似队列的结构,可以一直向队列中添加任务,当任务完成后便从队列中删除。如果队列中的任务没有完全完成,通过wait()函数来发出阻塞防止程序的继续进行,知道所有的进程都完成为止。
package main
import (
"sync"
"fmt"
"time"
)
func main(){
var w sync.WaitGroup
w.Add(3) //一共起来三个协程
go func() {
defer w.Done() // 在程序执行完成之后关闭此协程
for i := 0; i<5; i++{
fmt.Println(i)
}
}()
go func() {
defer w.Done() //同理
vmap := make(map[interface{}] interface{})
vmap["first"] = 333
vmap["second"] = "talking is cheap,show me the code!"
vmap["third"] = "23dsd"
//遍历集合,并输出key值和vallue值
for key,value := range vmap{
fmt.Println(key,value)
}
}()
//此协程是一个假协程,不做任何事,延缓协程的执行速度
go func() {
time.Sleep(time.Second)
w.Done()
}()
w.Wait() // 防止主程序main的提前结束
}
利用 go run main.go运行后输出结果为:
0
1
2
3
4
second talking is cheap,show me the code!
third 23dsd
first 333
Process finished with exit code 0
3. json编码解码
这一块呢感觉比较陌生,在实际应用过程中慢慢理解咯。
json是一种轻量级的数据交互格式,在将go数据转换为json数据时(编码)利用Marshal()函数,而将json数据转换为go数据时(解码)利用Unmarshal()函数。
但时,要注意一点:Json包只访问公开字段的结构体类型(以大写字母开头的那些),因此,只有公开字段的结构体才会出现在json输出中。
package main
import (
"fmt"
"encoding/json"
)
//go数据结构转换成json数据结构
func main(){
type person struct {
Id int
Name string
Country string
}
p := person{1,"HXH","china"}
fmt.Println(p)
k,err := json.Marshal(p)
if err != nil{
fmt.Println("转换失败!")
}else{
fmt.Println("json结果为:",k)
fmt.Println(string(k))
}
}
以上总结只是部分,后续问题再分享。