本文记录了我在学习Go的过程时的一些笔记,主要是比较Python和Go之间的差异并作简单描述,以此使Python程序员对Go语言的特性有简略的了解。初学难免有纰漏,欢迎各位批评指正补充交流,谢谢。

数组和slice

Go中的数组需要在创建时确定长度,一个更灵活的对象是slice,后者可以使用append添加,两者的定义方式相似。

  1. var StrArray [10]string //数组,长度为10
  2. var StrSlice []string //slice

slice可以根据现有的数组(称为底层数组)创建,但对其的修改会导致底层数组的改变。

指针

Go语言支持指针,用法和C一样

结构体

结构体和Python中的Class相似,但在这一代码段中只能定义类型的数据布局,方法需要定义指定接收对象的函数(见“方法”)。

  1. type Point struct{
  2. X int
  3. Y int
  4. }

结构体嵌套和匿名成员

在结构体中添加结构体成员会使变量的访问变得麻烦,Go中可以不带名称定义结构体成员称为匿名成员。

结合匿名成员以及方法对匿名成员的处理(包含某个结构体匿名成员的结构体可以接收该结构体的方法),匿名成员机制可以视为继承

  1. type ColoredPoint struct {
  2. Point // 匿名成员
  3. color string
  4. }
  5. var cp ColoredPoint
  6. cp.X = 1
  7. cp.Y = 2
  8. cp.color = "red"

函数和方法

不同于普通的函数,方法是指定接收对象的。

包含某个结构体匿名成员的结构体可以接收该结构体的方法。

接口

定义与实现

隐式实现:满足接口所需的方法即为实现某个接口,无需显式声明

  1. type Phone interface {
  2. call()()
  3. text(str []string)(n int)
  4. }

当某一个类型拥有如上所属的输入和输出的Write方法时,即可称其实现了Writer接口。

  1. type iPhone struct{}
  2. func (p iPhone) call (){
  3. fmt.Println("call from iPhone")
  4. }
  5. func (p iPhone) text (str []string){
  6. fmt.Println(str)
  7. fmt.Println("text from iPhone")
  8. return len(str)
  9. }

接口的应用

接口可以被作为一个变量定义,可被赋予具体类型。

  1. var phone Phone
  2. // 赋值方法一
  3. var iphone iPhone
  4. phone = iphone
  5. phone.call()
  6. phone.text("test")
  7. // 赋值方法二
  8. phone = new(iPhone)
  9. phone.call()
  10. phone.text("test")

并行

goroutine

Go中每一个并发的活动称为goroutine,不同于Python虚假的多线程或不稳定的多进程,goroutine被归类为协程(Coroutine)。

并行:多进程、多线程、协程、异步IO

  1. go f()

不同于Python会自动等待各Process运行结束后退出,在Go中main函数返回时,所有的goroutine都暴力地终结,可以使用下文提及的通道阻塞或者sync的WaitGroup等待以保证各goroutine运行。

通道

通道用于goroutine间的通信,不同于Python的Threading库或multiporcessing库中的Queue(队列),Go中的通道是需要标注数据类型的。

  1. ch := make(chan int) //定义通道,int为数据类型
  2. ch <- x // 发送数据
  3. x = <- ch // 接收数据
  4. <- ch // 接收数据并丢弃
  5. close(ch) //关闭通道

对通道的收发操作都是阻塞的。

不同于Queue关闭后无法收发,通道关闭后无法发送,但可以接收剩余的数据。

无缓冲通道

  1. ch1 := make(chan int)
  2. ch2 := make(chan int, 0)
  3. // 两者含义相同

如上定义的通道,为无缓冲通道,即一次不阻塞的发送后,数据被接收之前,第二次发送被阻塞。

缓冲通道

  1. ch := make(chan int, 3) //定义通道,int为数据类型,容量为3

如上定义的通道,可以进行四次不阻塞的发送,第五次发送被阻塞(没有接收的前提下)。

单向通道

为了避免误用可以在函数的参数定义时固定通道的方向

  1. func f(in <-chan int, out chan<- int) {}

如上定义时,通道in对于函数f来说是只能接收的通道,通道out对于函数f来说是只能发送的通道。

select多路复用

select的类似于switch,但不同的是select的分支上是阻塞着的操作而非数据。select使可以同时等待多个操作的阻塞,直到某一个分支上的操作不再阻塞。每个select只执行一个分支。

  1. select {
  2. case x1 <-ch1:
  3. // ...
  4. case x2 <-ch2:
  5. // ...
  6. case ch3 <- x3:
  7. // ...
  8. default:
  9. // ...
  10. }

共享变量

一句任何涉及并发的编程都应该遵守的话:

‘‘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程序设计语言》

从Python到Go:初学笔记的更多相关文章

  1. Python初学笔记之字符串

    一.字符串的定义 字符串是就一堆字符,可以使用""(双引号).''(单引号)来创建. 1 one_str = "定义字符串" 字符串内容中包含引号时,可以使用转 ...

  2. 学习《零基础入门学习Python》电子书PDF+笔记+课后题及答案

    初学python入门建议学习<零基础入门学习Python>.适合新手入门,很简单很易懂.前一半将语法,后一半讲了实际的应用. Python3入门必备,小甲鱼手把手教授Python,包含电子 ...

  3. C++ STL初学笔记

    C++  STL初学笔记 更系统的版本见徐本柱的PPT set 在这儿:http://www.cnblogs.com/pdev/p/4035020.html #include <vector&g ...

  4. Requests:Python HTTP Module学习笔记(一)(转)

    Requests:Python HTTP Module学习笔记(一) 在学习用python写爬虫的时候用到了Requests这个Http网络库,这个库简单好用并且功能强大,完全可以代替python的标 ...

  5. 关于Python网络爬虫实战笔记③

    Python网络爬虫实战笔记③如何下载韩寒博客文章 Python网络爬虫实战笔记③如何下载韩寒博客文章 target:下载全部的文章 1. 博客列表页面规则 也就是, http://blog.sina ...

  6. python网络爬虫学习笔记

    python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...

  7. Python学习的个人笔记(基础语法)

    Python学习的个人笔记 题外话: 我是一个大二的计算机系的学生,这份python学习个人笔记是趁寒假这一周在慕课网,w3cschool,还有借鉴了一些博客,资料整理出来的,用于自己方便的时候查阅, ...

  8. Spring 初学笔记

    Spring 初学笔记: https://blog.csdn.net/weixin_35909255/article/category/7470388

  9. Python Built-in Function 学习笔记

    Python Built-in Function 学习笔记 1. 匿名函数 1.1 什么是匿名函数 python允许使用lambda来创建一个匿名函数,匿名是因为他不需要以标准的方式来声明,比如def ...

  10. python高级编程读书笔记(一)

    python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...

随机推荐

  1. SystemVerilog 中的相等运算符:== or === ?

    1. 四值逻辑的逻辑运算 在对比SystemVerilog中的相等运算符之前,先来看一下三种最基本的逻辑运算符,下文中以·表示与运算,以+表示或运算,以'表示非运算.我们都知道在逻辑代数中,只有0和1 ...

  2. Vue前端基础学习

    vue-cli vue-cli 官方提供的一个脚手架(预先定义好的目录结构及基础代码,咱们在创建Maven项目的时可以选择创建一个骨架项目,这个骨架项目就是脚手架),用于快速生成一个vue项目模板 主 ...

  3. BFS经典面试题——C++版

    文章目录 蛇梯棋 单词接龙 青蛙过河 蛇梯棋 N x N 的棋盘 board 上,按从 1 到 N*N 的数字给方格编号,编号 从左下角开始,每一行交替方向. 例如,一块 6 x 6 大小的棋盘,编号 ...

  4. 6、基本数据类型(list)

    6.1.列表: 1.li = [1, 12, 9, "age", ["孙子涵", ["19", 10], "张涵予"], ...

  5. 基于Yarp实现内网http穿透

    Yarp介绍 YARP是微软开源的用来代理服务器的反向代理组件,可实现的功能类似于nginx. 基于YARP,开发者可以非常快速的开发一个性能不错的小nginx,用于代理http(s)请求到上游的ht ...

  6. Java:Java的^运算符详解

    按位异或运算符(^)是二元运算符,要化为二进制才能进行计算,在两个操作数中,如果两个相应的位相同,则运算结果为0,否则1:例如:int a=15:int b=a^8;运算结果为:a=15:b=7:a( ...

  7. HCNA Routing&Switching之动态路由协议RIP

    前文我们了解了动态路由的基本概念,以及动态路由和静态路由的区别,优缺点,动态路由的分类,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14995317.html ...

  8. linux驱动之获取设备树信息

    上一篇文章学习了字符设备的注册,操作过的小伙伴都知道上一篇文章中测试驱动时是通过手动创建设备节点的,现在开始学习怎么自动挂载设备节点和设备树信息的获取,这篇文章中的源码将会是我以后编写字符驱动的模板. ...

  9. NTP配置(广播模式并且无认证)

    1.服务器端 1.1服务器本地同步自己的时钟,否则无法对外提供NTP服务 [NTP]ntp refclock-master 3 [NTP]ntp refclock-master 127.127.1.1 ...

  10. C语言:监听键盘

    所谓键盘监听,就是用户按下某个键时系统做出相应的处理,本章讲到的输入输出函数也是键盘监听函数的一种,例如 getchar().getche().getch() 等.下面的代码演示了 getche() ...