golang基础语法学习
1.函数作为一等公民
2.驼峰命名法/大小写决定是否在包外见
3.包名应该是小写的单个单词命名
4. 包名应为其源码的基础名称,如encoding/base64,包名应为base64而不是encoding_base64
5.获取器:Go不对获取器( getter)或 设置器(setter)支持,开发人员需要编写获取器和设置器的方法 func (o *Object)Owner()string{}/ func (o *Object)SetOwner(user string){}
6.接口名:按照约定:只包含一个方法的接口应该以该方法的名称加er,比如Reader,Writer,Formatter,CloseNotifier等
7.若你的类型实现的方法与一个众所周知的类型的方法拥有相同的含义,那就用相同的命名,比如字符串转换方法命名为String而不是ToString
8.使用for range 遍历 数组或者切片
9.go与众不同的特性之一:函数和方法可以返回多个值。目的:为了改变C的笨习惯,将返回值比如-1表示EOF和通过地址传实参
10.go函数返回值或结果形参可被命名,并作为常规变量使用,就和传入的形参一样。
11.defer(LIFO)先进后出,典型应用:解锁互斥锁和关闭文件。
12. new分配内存会将内存置0,返回指针
13. make 只用于slice,map,channel,并且返回T而不是(*T)的一个已知初始化(而非置0)的值
```
var p *[]int = new([]int) //分配切片结构:*p == nil ;基本没用 返回切片指针
var v []int = make([]int,100) //切片v现在引用一个具有100个int元素的新数组
//没必要的方式
var p *[]int = new([]int)
*p = make([]int,100,100)
//等价于
var p = make([]int,100)
```
14 数值是值,将一个数组赋值给另外一个数组会复制其中所有元素
15 若将数组传入函数,它将接受到数组的值拷贝(副本)而不是指针
16 数组的大小是其类型的一部分,类型【10】int 和【20】int是不同的
17 切片保存了底层数组的引用,若你将某个切片赋予另一个切片,他们将会引用同一个数组。
18 切片函数对内容修改,可以直接传参,若使用append对其添加,则无效,原因是append会将原数组扩容,返回的仍然是原切片而已
19 Map字典,映射 若将map传入函数,并更改此映射的内容,则改修改对调用者可见
20 常量定义的表达式必须是可被编译器求值的常量表达式
21 Go中同时有函数和方法,方法就是一个包含了接收者(receiver)的函数
22 方法的接收着是否必须为结构体?不一定,任何类型都可以
23 go内置函数append
```
func Append(slice,data[]byte)[]byte{
l := len(slice)
if l + len(data) > cap(slice) {
newSlice := make([]byte,(l+len(data)*2))
copy(newSlice,slice)
slice = newSlice
}
slice = slice[0:l+len(data)]
for i,c:= range data{
slice[l+i] = c
}
return slice
}
//方法实现
type ByteSlice []byte
func (p *ByteSlice) Append(data []byte){
slice := *p
*p = slice
}
```
24 让ByteSlice实现io.Writer
实现Writer方法
```
type ByteSlice []byte
func (p *ByteSlice)Write(data []byte)(n int,err error){
slice := *p
*p = slice
return len(data),nil
}
```
25 接口 为指定对象的行为提供的一种约定:如果事情可以这么做,那么他就可以在这里使用,一个类型可以实现多个接口。
26 类型断言 value interface{} / value.(string)
27 隐藏接口的实现 (duck type)
```
type Block interface{
BlockSize() int
Encrypt(src,dst []byte)
Decypt(src, dst []byte)
}
type Stream interface{
XORKeyStream(dst,src []byte)
}
func NewCTR(block Block,iv []byte) Stream
```
NewCTR并不只是用于一个特定加密算法和数据源,而是用于对任何Block接口的实现和任何Stream
因为他们返回接口值,所有将CTR加密替换成为其它的加密模式知识一个局部的改变。客户不会感知,符合solid中依赖倒置原则
27 接口和方法
go中由于几乎任何事物都可以附加上方法,所有几乎(指针和接口类型除外)任何事物都满足接口的要求。
如下:任何实现了Handler的对象都可以为HTTP请求提供服务
```
type Handler interface{
ServeHTTP(ResponseWriter,*Request)
}
type Counter struct{
n int
}
func (ctr *Counter)ServeHTTP(w http.ResponseWriter,req *http.Request){
ctr.n++
fmt.Fprintf(w,"counter = %d\n",ctr.n)
}
//或者
type Counter int
func (ctr *Counter)ServeHTTP(w http.ResponseWriter,req *http.Request){
*ctr++
fmt.Fprintf(w,"counter = %d\n",*ctr)
}
```
28 如果一个类型只是用来实现接口,并且除了该接口以外没有其他被导入的方法,那就不需要导出这个类型,只导出接口,
清楚的表明其重要的是行为,而不是实现。
29 空白标志符的定义
1.忽略左值 (_),和Unix系统中向 /dev/null 文件中写入数据:它认为那些需要出现但值其实可以
忽略的变量提供一个只写的占位符
2. 未使用的左值或者import
3. 接口检测
30 内嵌的定义 embedding
1. 接口和结构体内嵌(接口只能内嵌接口类型)
2.结构体内嵌和继承的区别
2.1 结构体内嵌一个类型时,该类型所有的方法会变成外部类型的方法,但是当这些方法被调用时,其接受的参数仍然是内部类型,而不是外部类型
2.2 但其他语言的继承关系的话,方法变成子类的方法,并且方法调用时,接受的参数也是子类型的参数
```
type Logger struct{}
func(I Logger)Log(){
fmt.Printf("type of Log's recevier %T\n",I)
}
type Job struct{
name string
Logger
}
func (j Job)Work(){
fmt.Printf("type of work's recevier: %T\n",j)
}
func main(){
job := job{}
job.Log()
job.Work()
}
```
输出:
type of log's receiver : main.Logger
type of Work's receiver: main Job
30 并发
1 以通信实现共享并发理念
要考虑很多细节保证对共享变量访问的正确性,并发编程变得异常复杂
Go 采用了一种不同的方法,即共享变量通过Channel相互传递的方法解决上述问题
著名的口号
Do not Communicate by sharing memory; instead,share memory by communicating(不用通过共享内存来通信,而是通过通信来共享内存)
Go的并发模型源自CSP模型(communicating Sequential Processes 通信顺序进程)
在此并发模型下,任何时刻,仅有一个Goroutine可以访问到某个变量,这样数据竞争问题在设计上就被规避了。
2 Groutine的定义
每个Groutine都对应一个非常简单的模型:它是一个并发的函数执行线索,并且在多个并发的Goroutine间,资源
是共享的。Groutine很轻,初始化栈很小
添加一个Go关键词创建并调用方法,当函数执行结束后,Goroutine也会隐形退去
单独的goroutine并不实用,因为执行函数无法发布其完成信号,因此需要一个Channel结构
3 channel是Goroutine间进行通信的数据类型,与map类似,channel也是通过make分配的
其返回值实际上是一个执向相关数据结构的引用。
有两种类型:无缓冲channel,也称为同步channel
有缓冲channel
区别是make时,整形参数有无取值
ci := make(chan int);
cs: = make(chan *os.File,100)
无缓冲channel使通信 有值的交换 和 同步机制组合 共同保证两个执行Goroutines运行可控。(同步)
有缓冲channel则是让两个Goroutine可以并行处理自己的任务而不相互等待(异步)
假如主线程有3个任务要执行,其中两个任务没有依赖,可以并行,但是第三个任务必须要等前两个完成我们就可以使用无buffer的channel
```
func task1(done chan int){
fmt.Println("task1 done")
done <- 1
}
func task2(){
fmt.Prinln("task2 done")
}
func task3(){
fmt.Println("task3 done")
}
```
主线程启动了一个goroutine执行task1,然后执行task2,在task2完成后等待,task1的done信号完成后
再执行 task3
```
func main(){
done := make(chan int)
go task1(done)
task2()
<- done
task3()
}
```
出现的结果:task1和task2完成的时间不确定,但是,task3一定会等待1和2完成才开始执行
task1 done ==> task2 done ==> task3 done
task2 done ==> task1 done ==> task3 done
golang基础语法学习的更多相关文章
- Swift基础语法学习总结(转)
Swift基础语法学习总结 1.基础 1.1) swift还是使用// 和/* */ 来注释,并且/* */允许多行注释. 1.2) swift使用print和println打印,它的传参是一个泛型 ...
- Swift基础语法学习总结
Swift基础语法学习总结Swift高级语法学习总结Swift语法总结补充(一) 1.基础 1.1) swift还是使用// 和/* */ 来注释,并且/* */允许多行注释. 1.2) swift ...
- Python 基础语法学习(第一讲)---类的使用
[写在前面]:其实自学python有一段时间了,但是一直没想起来要写博客来记录自己的学习,今天才感觉要写点什么让自己学的更扎实一点,所以从今天开始更新python自学系列,希望看见文章的大佬们可以指点 ...
- Java基础语法学习
Java基础语法学习 1. 注释 单行注释: //单行注释 多行注释: /*多行注释 多行注释 多行注释 多行注释 */ 2. 关键字与标识符 关键字: Java所有的组成部分都需要名字.类名.变量名 ...
- java 基础语法学习01
Java基础语法 注释 初次使用idea时相关配置 new project ->Empty project->进入页面 再选择file->project structure-> ...
- Go基础语法学习
Go语言基础 Go是一门类似C的编译型语言,但是它的编译速度非常快.这门语言的关键字总共也就二十五个,比英文字母还少一个,这对于我们的学习来说就简单了很多.先让我们看一眼这些关键字都长什么样: 下面列 ...
- React基础语法学习
React主要有如下3个特点: 作为UI(Just the UI) 虚拟DOM(Virtual DOM):这是亮点 是React最重要的一个特性 放进内存 最小更新的视图,差异部分更新 diff算法 ...
- Xpath基础语法学习
背景: 之所以学习Xpath,是因为在学习selenium定位页面元素,总是定位不到元素.为了更好的开展自动化测试,先学习下Xpath. 一:Xpath是什么. 1:Xpath是一门在XML文档中查找 ...
- Swift基础语法学习总结一
1.基础 1.1) swift还是使用// 和/* */ 来注释,并且/* */允许多行注释. 1.2) swift使用print和println打印,它的传参是一个泛型,几乎所有类型都是可打印的. ...
- Java基础语法学习知识
基础概念 标识符1.由字母,数字,下划线,美元符组成2.首字母不能是数字3.不能是关键字和保留字4.能反映其作用 关键字1.有特定含义2.用于特定地方3.用来命名标识符 常量1.程序执行时值不变的量2 ...
随机推荐
- git stash总结
git stash 1. git stash save "message" 执行存储,并添加备注信息(直接git stash 也可以,但没有备注信息) 2. git stash ...
- C#winform中使用Cef的ChromiumWebBrowser内嵌谷歌内核,调用前端js方法
1.在winform中调用js方法: --调js中的方法无 入参形式 webBrowser1.ExecuteJavascript("logout()"); --调js中的方法给js ...
- bat脚本关闭、等待时间、启动程序、
@echo off ::关闭/杀死进程 @taskkill /f /IM Hos.exe ::等待10秒 start /min /w mshta vbscript:setTimeout("w ...
- linux下搭建ftp文件服务器
linux下搭建ftp文件服务器 一.搭建步骤(以在centos7中搭建为例) 1.首先检查一下系统中是否已经安装了vsftpd软件 # 查看是否安装vsftpd rpm -q vsftpd rpm ...
- 命令行配置Windows高级防火墙
今天正好看到个帖子,询问如何通过命令行配置防火墙策略中远程IP的地址,特别是添加新的地址. 就是图中Scope里Remote IP address的地址. 第一反应就是用netsh firewall来 ...
- 国产CPLD(AGM1280)试用记录——做个SPI接口的任意波形DDS [原创www.cnblogs.com/helesheng]
我之前用过的CPLD有Altera公司的MAX和MAX-II系列,主要有两个优点:1.程序存储在片上Flash,上电即行,保密性高.2.CPLD器件规模小,成本和功耗低,时序不收敛情况也不容易出现.缺 ...
- 最强cron解析器
背景 大家有没有这么一种困境 我现在需要去配置一个定时任务:"每天早上九点执行任务" 若你有一个好的定时任务平台,相信很容易就能配置完成.那若是没有定时任务平台呢?是不是就要自己写 ...
- Keepalived+HAProxy 搭建高可用负载均衡
转载自:https://mp.weixin.qq.com/s/VebiWftaRa26x1aA21Jqww 1. 概述 软件负载均衡技术是指可以为多个后端服务器节点提供前端IP流量分发调度服务的软件技 ...
- 使用mtr来判断网络丢包和网络延迟
转载自:https://mp.weixin.qq.com/s/UsjzMS1_rdxenw0TPlqwyQ 常用的 ping,tracert,nslookup 一般用来判断主机的网络连通性,其实 Li ...
- Kubernetes实践技巧:升级为集群
高可用 前面我们课程中的集群是单 master 的集群,对于生产环境风险太大了,非常有必要做一个高可用的集群,这里的高可用主要是针对控制面板来说的,比如 kube-apiserver.etcd.kub ...