go学习笔记(强类型的静态无虚拟机语言)
“业务逻辑”和“控制逻辑”分离解耦的编程模式 a. 反转控制: 开关和各种电器,不是将开关放在电器中,而是将开关抽象出来,由电器依赖开关,这样实现开关模块的独立和复用。 b. map、redunce、filter c. reflect d. 目前go 的泛型编程基于interface
修饰器编程模式
编程范式:过程式编程procedural、函数式编程functional、面向对象编程object-oriented
c语言特征:
- C 语言是一个静态弱类型语言,在使用变量时需要声明变量类型,但是类型间可以有隐式转换;
- 不同的变量类型可以用结构体(struct)组合在一起,以此来声明新的数据类型;
- C 语言可以用 typedef 关键字来定义类型的别名,以此来达到变量类型的抽象;
- C 语言是一个有结构化程序设计、具有变量作用域以及递归功能的过程式语言;
- C 语言传递参数一般是以值传递,也可以传递指针;
- 通过指针,C 语言可以容易地对内存进行低级控制,然而这加大了编程复杂度;
- 编译预处理让 C 语言的编译更具有弹性,比如跨平台。
C 语言的伟大之处 使用 C 语言的程序员在高级语言的特性之上还能简单地做任何底层上的微观控制
c语言设计理念:
- 相信程序员;
- 不会阻止程序员做任何底层的事;
- 保持语言的最小和最简的特性;
- 保证 C 语言的最快的运行速度,那怕牺牲移值性。
程序语言的类型系统提供的能力:
- 程序语言的安全性
- 利于编译器的优化(字节对齐、机器指令更高效)
- 代码的可读性(函数、接口的定义更清晰)
- 抽象化
- 带来的问题:类型的多态(类型带来的问题就是我们作用于不同类型的代码,虽然长得非常相似,但是由于类型的问题需要根据不同版本写出不同的算法,如果要做到泛型,就需要涉及比较底层的玩法。)
- 类型的定义:类型是对底层内存布局的一个抽象,不同的类型,会有不同的内存布局和内存分配的策略。不同的类型,有不同的操作。所以,对于特定的类型,也有特定的一组操作。
类型的检查:
- 静态类型检查: 是在编译器进行语义分析时进行的。如果一个语言强制实行类型规则(即通常只允许以不丢失信息为前提的自动类型转换),那么称此处理为强类型(go),反之称为弱类型(c)。
- 动态类型检查: 系统更多的是在运行时期做动态类型标记和相关检查(检查工作交给程序员)。所以,动态类型的语言必然要给出一堆诸如:is_array(), is_int(), is_string() 或是 typeof() 这样的运行时类型检查函数。
泛型的标准:
- 标准化掉类型的内存分配、释放和访问。
- 标准化掉类型的操作。比如:比较操作,I/O 操作,复制操作……
- 标准化掉数据容器的操作。比如:查找算法、过滤算法、聚合算法……
- 标准化掉类型上特有的操作。需要有标准化的接口来回调不同类型的具体操作……
实现泛型的方式:
- 通过类中的构造、析构、拷贝构造,重载赋值操作符,标准化(隐藏)了类型的内存分配、释放和复制的操作。
- 通过重载操作符,可以标准化类型的比较等操作。
- 通过 iostream,标准化了类型的输入、输出控制。
- 通过模板技术(包括模板的特化),来为不同的类型生成类型专属的代码。
- 通过迭代器来标准化数据容器的遍历操作。
- 通过面向对象的接口依赖(虚函数技术),来标准化了特定类型在特定算法上的操作。
- 通过函数式(函数对象),来标准化对于不同类型的特定操作。
泛型编程的理解: 屏蔽掉数据和操作数据的细节,让算法更为通用,让编程者更多地关注算法的结构,而不是在算法中处理不同的数据类型
函数式编程: 核心: map、reduce、filter,pipline模式,decorator模式。 Decorator 这个函数其实是可以修饰几乎所有的函数的。于是,这种可以通用于其它函数的编程方式,可以很容易地将一些非业务功能的、属于控制类型的代码给抽象出来(所谓的控制类型的代码就是像 for-loop,或是打日志,或是函数路由,或是求函数运行时间之类的非业务功能性的代码)
编程的本质 1. Programs = Algorithms + Data Structures 2. Algorithm = Logic + Control 有效地分离 Logic、Control 和 Data 是写出好程序的关键所在!
绝大多数程序复杂混乱的根本原因:业务逻辑与控制逻辑的耦合。
go 语言资料:
https://time.geekbang.org/column/article/8701https://github.com/avelino/awesome-go