谈一谈编程系列之一
data: 2017-8-13 22:07:36
title: 谈一谈编程系列之一
最近看不同语言的基础比较多,前一段时间又补了几本底层的书,总归有想写点什么的冲动,于是开了一个系列,《谈一谈编程》,这里是系列之一。
初衷:计算机是以纯粹人类理性构建起来的学科。
this
关于 this
的探讨来自 ES6 的 arrow function
(箭头函数),先看代码:
// 将数组中的每个数 ×2
const double = nums.map(function(num){
console.log(this); // window
retrun num*2;
});
const double = nums.map((num) => num*2); // parent
前一种写法,this
指向当前回调函数,而回调函数,属于当前 window
,所以这里的 this
实际上指向的是 window
;
后一种写法是 ES6 新增的箭头函数,this
指向自己的父类。
所以,这个看起来像「语法糖」的改动,其实并不是简单的将 function(){}
这种格式给简化了,有兴趣可以用 babel
帮你翻译成以前的版本试试。
当然,还没完,再看看:
<?php
class Test
{
private $a;
public function getA()
{
return $this->a;
}
}
有点 hello world
的既视感,是的,这个确实很简单,但是这个就是为了说明 this
的本质:当前实例化的类。把这个本质再套到上面去看看。
赋值、引用、拷贝
先不谈浅拷贝、深拷贝、写时拷贝这些更深一层的概念,还是先看简单代码:
a = b = 1
a = 2
print(a, b) # a b 不同
a= b = [1,2,3]
a[0] = 4
print(a, b) # a b 相同
直接说一下结论:赋值生成引用。引用?引用 == 指针?但是这里没有用 &
符号呀。所以,这里要好好说道一下 a = 1
这个赋值语句了:
- 分配内存给 1 这个数
- 分配内存给变量 a
-
=
号其实建立的是 a 到 1 的联系(引用)
继续说本质:既要给变量分配内存,也要给数据分配内存,还要给二者建立起联系。好好对比一下这个例子,顺便可以试试下面这个:
import sys
sys.getrefcount(1) # 引用计数:98
我们还没写具体代码,1 这个数据的引用计数就有 98 个。
关于引用计数这个再啰嗦:
- 动态语言有 gc(垃圾回收)机制的,其中一个实现就是把引用计数为 0 的数据清理掉;
- 引用要形成环了怎么办?(这个可以参考 php5.4 的更新内容,里面就有这方面的优化)。
聊完了引用,问题也就出来了,有时我们就是需要一份一样的数据,然后两份数据不要相互影响。当然可以,内存中复制一遍,这就是拷贝了。
比较一下两者的本质,一个只需要建立一下联系,一个却要分配内存并写入数据,开销 不一样。所以,会出现这样一个关键字:clone
。同时也想指出,类的创建和销毁需要很大的开销的。
再回到一开始列的几个概念,本质其实是:建立缓冲,削弱拷贝带来的开销。这里讲讲「写时拷贝」。
如果接触过「高性能服务器开发」或者看过《现代计算机操作系统》,这个词就不会陌生了,操作系统的惯用套路。其实就是一种 延时 机制,数据到需要 写 的时候才 复制,不到这一刻,就没必要提前付出代价。
小结
只是想 抛砖引玉 一下,基本都是飘过,得到知识是一个渐进与构建的过程。
畅销书往往会夸大,只是到最后,你还是发现你需要那些大部头。