Python 编程 5 年后,我转向了 Go!
作为如今火了半边天的动态语言 Python ,凭借着较强的灵活性、可移植、可扩展等特性广受开发者喜爱。但是和 Google 的第二款开源编程语言 Go 相比,Python 的性能完全处于较弱一方。
在此局面下,“弃 Python 而拥抱 Go”的言论不绝于耳,但是我们究竟该怎么做才能迁移成功?其中又有哪些值得关注的点?在本文中,作者不论语言好坏,只谈从 Python 到 Go 的经验分享,希望对大家有所裨益。
我喜欢Python。在过去的五年里,它一直是我的首选语言。Python非常友好并且易于学习,同时还保持着超级的效率。
从创建简单的脚本和Web开发,到数据可视化和机器学习,你几乎可以随时使用它。
但随着Go的逐渐成熟、强大的用户基础,以及越来越多的公司在经过成功的基准测试后决定转向Go的事实,使我更加广泛地阅读了Go,同时思考如何将其添加到我的工具集中并将它的好处应用到我的工作当中。
这篇文章不会讨论Python或Go哪种编程语言更好,线上有很多关于这个主题的帖子和比较,而且我认为这种问题在很大程度上取决于项目。
在这篇文章中,我将告诉你我从Python到Go的旅程,并为你提供一些技巧,让你了解一些帮助我在这次旅程中取得成功的资源。
我遇到的主要差异
当然,作为第一步,我浏览了令人叹为观止的官方“Tour Of Go”(https://tour.golang.org/welcome/),这确实让我有了良好的关于Go语法的基础知识。
为了加强这些知识,我阅读了电子书Go for Python Programmers,这使我能够继续下一步,尝试和失败,我认为这是最具教育意义的。
我使用了以前在Python中使用的常用函数,如JSON序列化或使用HTTP调用,并尝试在Go中编写它们。
通过在Go中应用来自Python中的类似概念,同时仍然包含语言的静态特性,我遇到了Go和Python之间的一些关键性的差异。
1.项目布局
首先,Python典型的不需要特定的目录层次结构,而Go则另外需要。
Go使用“标准”布局,这种布局稍微复杂一点,这使得增加了更多的工作,但好处是拥有结构良好的代码基础。这种代码基础鼓励模块化代码,并在项目规模扩大时仍能保持有序性。
2.静态和强类型
Go是一种静态类型的语言,由于你习惯使用Python或Ruby等动态类型语言,因此最初会让你感到不舒服。
毫无疑问,动态语言更容易出错,并且在输入验证方面需要花费更多精力来防止常见语法错误或解析错误。思考一个函数,他是计算两个整数之和的函数,但实际上你并不能保证使用此函数的用户不会将字符串传递给函数,因此这就会导致TypeError。
这种情况不会发生在Go中,因为你需要声明每个变量的类型,也就是说你的函数可以获得哪种类型的变量,以及函数将返回哪种类型的变量。
起初它有点烦人,感觉它让我的编码速度慢了很多,但是在很短的时间的阅读和编写Go的代码后,你发现已经习惯它了,它实际上可以节省时间,并使你的代码更加的鲁棒。
3.天生的并发性
Go具有天生的并发特性它支持使用goroutines和channel,这些可以使并发非常的方便。
首先,channel的概念可能有点棘手,并且很容易将其视为某种数据结构或排队实现。但是,经过一些阅读后,它们变得更加直白,你可以真正享受它们带来的价值,并充分利用它们。
如下是,一个简单的可视化的goroutines和channel:
packagemain
funcmain(){
// create new channel of type int
ch :=make(chanint)
// start new anonymous goroutine
gofunc(){
// send 42 to channel
ch <-42
}()
// read from channel
<-ch
}
有关更多示例,请查看Hootsuite real life implementation,一个来自ArdanLabs的优秀解释。
4.使用JSON
好吧,不再有json.loads()给你使用。
在Python中,反序列化JSON对象非常简单,只需使用json.loads就可以了!
但是在Go中,作为一种静态类型语言,这种简单的操作可能会更复杂。
在Go中,你将JSON解析为之前定义的结构。任何不适合结构的字段都将被忽略,这是一件好事。这可以将其视为双方之间的一种预定义协议。这种方式下,你不需要对JSON中收到的数据感到“吃惊”,并且JSON字段和类型需要由双方“同意”。
{
“first”: “Elad”,
“last”: “Leev”,
“location”:”IL”,
“id”: “93”
}
type AccountDatastruct{
Firststring`json:"first"`
Laststring`json:"last"`
Locationstring`json:"location"`
IDstring`json:"id"`
}
当然,你仍然可以在没有结构的情况下反序列化JSON,但是如果可能的话应该避免使用它,毕竟拥抱语言的静态性总归是更好的。
5.清洁的代码
Go编译器将始终尽力保持代码清洁。
Go编译器将未使用的变量视为编译错误,而且,Go采用了独特的方法让机器处理大多数格式问题。
Go将在保存或编译时运行gofmt程序,它将处理大多数格式问题。
你不关心其中一个变量?再次 - 没问题!只需使用_(下划线)并将其分配给空标识符就可以了。
我的旅程还在继续