从Python到Go:初学笔记
本文记录了我在学习Go的过程时的一些笔记,主要是比较Python和Go之间的差异并作简单描述,以此使Python程序员对Go语言的特性有简略的了解。初学难免有纰漏,欢迎各位批评指正补充交流,谢谢。
数组和slice
Go中的数组需要在创建时确定长度,一个更灵活的对象是slice,后者可以使用append添加,两者的定义方式相似。
var StrArray [10]string //数组,长度为10
var StrSlice []string //slice
slice可以根据现有的数组(称为底层数组)创建,但对其的修改会导致底层数组的改变。
指针
Go语言支持指针,用法和C一样
结构体
结构体和Python中的Class相似,但在这一代码段中只能定义类型的数据布局,方法需要定义指定接收对象的函数(见“方法”)。
type Point struct{
X int
Y int
}
结构体嵌套和匿名成员
在结构体中添加结构体成员会使变量的访问变得麻烦,Go中可以不带名称定义结构体成员称为匿名成员。
结合匿名成员以及方法对匿名成员的处理(包含某个结构体匿名成员的结构体可以接收该结构体的方法),匿名成员机制可以视为继承
type ColoredPoint struct {
Point // 匿名成员
color string
}
var cp ColoredPoint
cp.X = 1
cp.Y = 2
cp.color = "red"
函数和方法
不同于普通的函数,方法是指定接收对象的。
包含某个结构体匿名成员的结构体可以接收该结构体的方法。
接口
定义与实现
隐式实现:满足接口所需的方法即为实现某个接口,无需显式声明
type Phone interface {
call()()
text(str []string)(n int)
}
当某一个类型拥有如上所属的输入和输出的Write方法时,即可称其实现了Writer接口。
type iPhone struct{}
func (p iPhone) call (){
fmt.Println("call from iPhone")
}
func (p iPhone) text (str []string){
fmt.Println(str)
fmt.Println("text from iPhone")
return len(str)
}
接口的应用
接口可以被作为一个变量定义,可被赋予具体类型。
var phone Phone
// 赋值方法一
var iphone iPhone
phone = iphone
phone.call()
phone.text("test")
// 赋值方法二
phone = new(iPhone)
phone.call()
phone.text("test")
并行
goroutine
Go中每一个并发的活动称为goroutine,不同于Python虚假的多线程或不稳定的多进程,goroutine被归类为协程(Coroutine)。
并行:多进程、多线程、协程、异步IO
略
go f()
不同于Python会自动等待各Process运行结束后退出,在Go中main函数返回时,所有的goroutine都暴力地终结,可以使用下文提及的通道阻塞或者sync的WaitGroup等待以保证各goroutine运行。
通道
通道用于goroutine间的通信,不同于Python的Threading库或multiporcessing库中的Queue(队列),Go中的通道是需要标注数据类型的。
ch := make(chan int) //定义通道,int为数据类型
ch <- x // 发送数据
x = <- ch // 接收数据
<- ch // 接收数据并丢弃
close(ch) //关闭通道
对通道的收发操作都是阻塞的。
不同于Queue关闭后无法收发,通道关闭后无法发送,但可以接收剩余的数据。
无缓冲通道
ch1 := make(chan int)
ch2 := make(chan int, 0)
// 两者含义相同
如上定义的通道,为无缓冲通道,即一次不阻塞的发送后,数据被接收之前,第二次发送被阻塞。
缓冲通道
ch := make(chan int, 3) //定义通道,int为数据类型,容量为3
如上定义的通道,可以进行四次不阻塞的发送,第五次发送被阻塞(没有接收的前提下)。
单向通道
为了避免误用可以在函数的参数定义时固定通道的方向
func f(in <-chan int, out chan<- int) {}
如上定义时,通道in对于函数f来说是只能接收的通道,通道out对于函数f来说是只能发送的通道。
select多路复用
select的类似于switch,但不同的是select的分支上是阻塞着的操作而非数据。select使可以同时等待多个操作的阻塞,直到某一个分支上的操作不再阻塞。每个select只执行一个分支。
select {
case x1 <-ch1:
// ...
case x2 <-ch2:
// ...
case ch3 <- x3:
// ...
default:
// ...
}
共享变量
一句任何涉及并发的编程都应该遵守的话:
‘‘Do not communicate by sharing memory; instead, share memory by communicating.’’
不要通过共享内存来通信,应该用通信来共享内存。即应当将对象限制在顺序执行的环境下(比如某个协程中)进行写操作。
互斥锁
也可以用锁。
sync.Mutex
类似multiprocessing.Lock有acquire()和release(),sync.Mutex有Lock()和Unlock()。(记得用defer延迟执行Unlock()以保证解锁的执行)
sync.RWMutex
Go提供共了一种更复杂的锁,除了不可并行的写锁Lock()和Unlock(),还有可并行的读锁RLock()和RUnlock()。其使用类似于数据库的二、三级封锁协议。
sync.Once
延迟初始化,Once函数以某个函数为参数,保证这个只需要执行一次的函数在并行情况下执行且只执行一次。相同效果虽然用RWMutex也可以实现但Once更加简便
竞态检测器 race detector
输出一份包含所有数据竞态的报告,go run/build/test时添加-race可以使用该功能。
GOMAXPROCS
确定需要使用的OS线程数目,可以在作为环境变量设置,或用函数runtime.GOMAXPROCS控制。
参考:
《Go程序设计语言》
原文地址:https://www.cnblogs.com/yc0806/p/15128953.html
- WCF后续之旅(11): 关于并发、回调的线程关联性(Thread Affinity)
- 解决文本框在updatepanel中得到焦点,输入法不能切换到中文的问题
- 得到真实外网IP、IP所在国家、省份、地区
- 机器学习在智能制造中的应用!
- sql2008 附加数据库时 错误5123
- Logistic Regression Models分析交互式问答译
- 照虎画猫写自己的Spring——依赖注入
- Logistic Regression Models分析交互式问答译
- Asp.Net开发等级星使用(Jquery Rating)
- Enterprise Library Policy Injection Application Block 之四:如何控制CallHandler的执行顺序
- 人工智能时代的艺术
- asp.net生成静态页
- Enterprise Library深入解析与灵活应用(1):通过Unity Extension实现和Policy Injection Application Block的集成
- 照虎画猫写自己的Spring
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 工具开发|Burp插件Unexpected_information
- 爱了!安利一个相见恨晚的可视化学习网站
- pandas+PyQt5轻松制作数据处理工具
- Python高效编程之88条军规(1):编码规范、字节序列与字符串
- 这是一份 pip 常用命令小结~
- 太震撼了,我用python画出全北京的公交线路动图
- 小伙Python爬虫并自制新闻网站,太好玩了
- TRTC Android端开发接入学习之视频会议(八)
- MySQL锁都分不清,怎么面试进大厂?
- Kubernetes Controller高可用诡异的15mins超时
- 这几项超好用的云开发扩展能力,别说你还不知道!
- Ubuntu上一键卸载安装mysql脚本
- Python-批量修改图片全部颜色,批量修改图片的指定颜色,马甲包一键换主题UI
- 【SpringBoot DB 系列】h2databse 集成示例 demo
- MySQL 案例:analyze,慢查询,与查询无响应