分享

编译一个大型的C或者C++项目Go语言进阶推荐这样三本书

 山峰云绕 2022-05-06 发布于贵州省

https://m.toutiao.com/is/FBKR1hJ/?=编译一个大型的C或者C++程序 


编译一个大型的C或者C++项目所花费的时间甚至比去喝杯咖啡的时间还长。图1-1是XKCD中的一幅漫画,描述了在办公室里开小差的经典借口。

图1-1 努力工作?(来自XKCD)

Go语言使用了更加智能的编译器,并简化了解决依赖的算法,最终提供了更快的编译速度。编译Go程序时,编译器只会关注那些直接被引用的库,而不是像Java、C和C++那样,要遍历依赖链中所有依赖的库。因此,很多Go程序可以在1秒内编译完。在现代硬件上,编译整个Go语言的源码树只需要20秒。

因为没有从编译代码到执行代码的中间过程,用动态语言编写应用程序可以快速看到输出。代价是,动态语言不提供静态语言提供的类型安全特性,不得不经常用大量的测试套件来避免在运行的时候出现类型错误这类bug。

想象一下,使用类似JavaScript这种动态语言开发一个大型应用程序,有一个函数期望接收一个叫作ID的字段。这个参数应该是整数,是字符串,还是一个UUID?要想知道答案,只能去看源代码。可以尝试使用一个数字或者字符串来执行这个函数,看看会发生什么。在Go语言里,完全不用为这件事情操心,因为编译器就能帮用户捕获这种类型错误。

Go语言的类型系统

Go语言提供了灵活的、无继承的类型系统,无需降低运行性能就能最大程度上复用代码。这个类型系统依然支持面向对象开发,但避免了传统面向对象的问题。如果你曾经在复杂的Java和C++程序上花数周时间考虑如何抽象类和接口,你就能意识到Go语言的类型系统有多么简单。Go 开发者使用组合(composition)设计模式,只需简单地将一个类型嵌入到另一个类型,就能复用所有的功能。其他语言也能使用组合,但是不得不和继承绑在一起使用,结果使整个用法非常复杂,很难使用。在Go语言中,一个类型由其他更微小的类型组合而成,避免了传统的基于继承的模型。

另外,Go语言还具有独特的接口实现机制,允许用户对行为进行建模,而不是对类型进行建模。在Go语言中,不需要声明某个类型实现了某个接口,编译器会判断一个类型的实例是否符合正在使用的接口。Go标准库里的很多接口都非常简单,只开放几个函数。从实践上讲,尤其对那些使用类似Java的面向对象语言的人来说,需要一些时间才能习惯这个特性。

1.类型简单

Go语言不仅有类似intstring这样的内置类型,还支持用户定义的类型。在Go语言中,用户定义的类型通常包含一组带类型的字段,用于存储数据。Go语言的用户定义的类型看起来和C语言的结构很像,用起来也很相似。不过Go语言的类型可以声明操作该类型数据的方法。传统语言使用继承来扩展结构——Client继承自User,User继承自Entity,Go语言与此不同,Go开发者构建更小的类型——Customer和Admin,然后把这些小类型组合成更大的类型。图1-4展示了继承和组合之间的不同。

图1-4 继承和组合的对比

2.Go接口对一组行为建模

接口用于描述类型的行为。如果一个类型的实例实现了一个接口,意味着这个实例可以执行一组特定的行为。你甚至不需要去声明这个实例实现某个接口,只需要实现这组行为就好。其他的语言把这个特性叫作鸭子类型——如果它叫起来像鸭子,那它就可能是只鸭子。Go语言的接口也是这么做的。在Go语言中,如果一个类型实现了一个接口的所有方法,那么这个类型的实例就可以存储在这个接口类型的实例中,不需要额外声明。

在类似Java这种严格的面向对象语言中,所有的设计都围绕接口展开。在编码前,用户经常不得不思考一个庞大的继承链。下面是一个Java接口的例子:

interface User { public void login(); public void logout();}

在Java中要实现这个接口,要求用户的类必须满足User接口里的所有约束,并且显式声明这个类实现了这个接口。而Go语言的接口一般只会描述一个单一的动作。在Go语言中,最常使用的接口之一是io.Reader。这个接口提供了一个简单的方法,用来声明一个类型有数据可以读取。标准库内的其他函数都能理解这个接口。这个接口的定义如下:

type Reader interface {    Read(p []byte) (n int, err error)}

为了实现io.Reader这个接口,你只需要实现一个Read方法,这个方法接受一个byte切片,返回一个整数和可能出现的错误。

这和传统的面向对象编程语言的接口系统有本质的区别。Go语言的接口更小,只倾向于定义一个单一的动作。实际使用中,这更有利于使用组合来复用代码。用户几乎可以给所有包含数据的类型实现io.Reader接口,然后把这个类型的实例传给任意一个知道如何读取io.Reader的Go函数。

Go语言的整个网络库都使用了io.Reader接口,这样可以将程序的功能和不同网络的实现分离。这样的接口用起来有趣、优雅且自由。文件、缓冲区、套接字以及其他的数据源都实现了io.Reader接口。使用同一个接口,可以高效地操作数据,而不用考虑到底数据来自哪里。

GO语言进阶图书推荐

Go语言定制指南

研究Go语言语法的实现方式,是学习软件设计和实现技术的最好方法。虽然大多数程序员从事的是应用程序或其他系统程序的开发工作,并不需要了解编译器的原理与实现,但是他们依然可以从本书受益,原因有以下几个。

(1)理解语言语法树的工作原理可以提升编程技能。Go语言语法树涵盖了常见的数据结构和算法,程序员通过深入学习能够更好地掌握语言本身及基础算法在现代计算机上的高效实现,进而应用到他们未来的开发工作中。

(2)编译器是Go语言反射技术的另一种形态。通过手动方式解析语法树可以得到远超反射技术可以获取的信息,从而在编译时可以灵活地输出更高效的辅助代码,极大地释放元编程的能力。例如,通过Go语言语法树可以很容易地从Go语言的结构体中提取出Kubernetes的CRD结构。

(3)本书通过类似组装计算机的方式避免初学者从刚开始就陷入浩瀚繁杂的编译理论。本书先基于Go语言语法树快速组装出可以马上运行的凹语言,帮助读者快速理解Go语言底层的运行机制,便于后面更深刻地理解Go语言的特性。

本书从Go语言语法树出发,重新审视Go语言源文件,阐述定制Go语言的核心技术。书中通过对go/ast、go/ssa等包的分析,一步步深入Go语言核心,最后简要介绍LLVM,读者可以结合LLVM和Go语言语法树按需定制,创造一个语法与Go语言语法类似的简单的编程语言及与其对应的编译器,达到掌握自制编程语言和编译器的目的。

本书面向已经熟练掌握Go语言并在进行项目开发的程序员,也适合想深入了解Go语言底层运行机制的程序员阅读,同时可作为对编程语言/编译器有兴趣并想进行实际项目实践的程序员的参考书。

Go语言高级编程

本书从实践出发讲解Go语言的进阶知识。本书共6章,第1章简单回顾Go语言的发展历史;第2章和第3章系统地介绍CGO编程和Go汇编语言的用法;第4章对RPC和Protobuf技术进行深入介绍,并讲述如何打造一个自己的RPC系统;第5章介绍工业级环境的Web系统的设计和相关技术;第6章介绍Go语言在分布式领域的一些编程技术。书中还涉及CGO和汇编方面的知识,其中CGO能够帮助读者继承优秀的软件遗产,而在深入学习Go运行时,汇编对于理解各种语法设计的底层实现是必不可少的知识。此外,本书还包含一些紧跟潮流的内容,介绍开源界流行的gRPC及其相关应用,并讲述Go Web框架中的基本实现原理和大型Web项目中的技术要点,引导读者对Go语言进行更深入的应用。

本书适合对Go语言的应用已经有一些心得,并希望能够深入理解底层实现原理或者是希望能够在Web开发方面结合Go语言来实现进阶学习的技术人员学习和参考。

Go语言实战

本书是写给已经有一定其他语言编程经验,并且想学习Go语言的中级开发者的。我们写这本书的目的是,为读者提供一个专注、全面且符合语言习惯的视角。我们同时关注语言的规范和实现,涉及的内容包括语法、类型系统,并发、通道、测试以及其他一些主题。我们相信,对于刚开始学Go语言的人,以及想要深入了解这门语言内部实现的人来说,本书都是极佳的选择。

本书由9章组成,每章内容简要描述如下。

  • 第1章快速介绍这门语言是什么,为什么要创造这门语言,以及这门语言要解决什么问题。这一章还会简要介绍一些Go语言的核心概念,如并发。
  • 第2章引导你完成一个完整的Go程序,并教你Go作为一门编程语言必须提供的特性。
  • 第3章介绍打包的概念,以及搭建Go工作空间和开发环境的最佳实践。这一章还会展示如何使用Go语言的工具链,包括获取和构建代码。
  • 第4章展示Go语言内置的类型,即数组、切片和映射。还会解释这些数据结构背后的实现和机制。
  • 第5章详细介绍Go语言的类型系统,从结构体类型到具名类型,再到接口和类型嵌套。这一章还会展示如何综合利用这些数据结构,用简单的方法来设计结构并编写复杂的软件。
  • 第6章深入展示Go调度器、并发和管道是如何工作的。这一章还将介绍这个方面背后的机制。
  • 第7章基于第6章的内容,展示一些实际开发中用到的并发模式。你会学到为了控制任务如何实现一个goroutine池,以及如何利用池来复用资源。
  • 第8章对标准库进行探索,深入介绍3个包,即logjsonio。这一章专门介绍这3个包之间的某些复杂关系。
  • 第9章以如何利用测试和基准测试框架来结束全书。读者会学到如何写单元测试、表组测试以及基准测试,如何在文档中增加示例,以及如何把这些示例当作测试使用。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多