程序 = 数据结构+算法
一开始,程序 = 算法
- 一开始数据结构可以没有(严格说来不可能,就简单的称为“只使用编程语言内置的类型,不同语言支持的类型不太一样,但是int,float,string是比较通用的类型”)
- 此时,程序就退化为纯粹的算法。这个时候程序几乎是无状态的。
- 函数接受输入,产生输出,这很符合unix的哲学(Modularity:)写简单的程序,并用好的接口连接它们;
// 猜猜这是干啥的(可以在go项目下面试试)
find `pwd` -name "*_test.go" | xargs -I {} grep -nr "Test" .| awk -F '/' '{print $2}'| uniq
然后,数据结构…
数据结构目的,无外乎:
- 数据结构影响算法效率 :
- 比如常见的数组(查找)、链表(插入删除)、树(查找)、图(搜索)等结构
- 几个变量绑定,就放到一起
- 比如:天气是和日期绑定的,生日是和历法绑定的(公农历)
- 如果要写函数表现一个人的生日,或者是一天的天气,最好的办法就是把这两个类型的数据绑定到一起
- 函数的参数列表太长(十几个),封装为数据结构
函数式:数据结构+算法
- 这个时候,函数依然接受输入,产生输出,不修改变量
- 不同点在于,有了数据结构,函数描述起来更加清晰了
- 函数式编程的好处在于,实现简单,容易测试,不易出错,并发安全
- 劣势在于,扩展性不好,对于高级的设计模式(接口、范型)支持不足
方法:数据结构⊇算法
- 有时候,函数的参数,或者返回值只有一个数据结构,这个时候就比较适合把函数当作数据结构的一个方法了
- 有时候,数据结构只希望提供有限访问(只读、加锁),也会提供get/set方法来访问私有变量
Go的骚操作
struct{}
做接收者
// 一个目的在于,在一个包里,划分几个业务领域
type Coder struct{}
func (Coder) EncodeInt(v int) string
func (Coder) EncodeJson(j Json) string
type Decoder struct{}
func (Decoder) DecodeInt(v string) int
func (Decoder) DecodeJson(v string) Json
函数做接收者
// 一个目的在于实现范型
type Option interface {
Do()
}
type f1 func()
func (f f1) Do {Pirntln("hello");f()}
type f2 func()
func (f f2) Do {Pirntln("world");f()}
var opt1 f1 = func() {}
var opt2 f2 = func() {}
var opts = []Option{ opt1, opt2,}