IT Notes‎ > ‎Programming Language‎ > ‎

匿名性问题讨论:Lua 中的函数和 Java 中的对象

在学习 Lua 的过程了解到 table 和函数的匿名性,分别在《第二章 类型和值》和《第六章 深入函数》中有提到。这种提法对理解 Java 中的对象,很有启发。

Lua 中函数的匿名性

以系统函数  math.sin 为例,用青色矩形表示函数本身,要是用这个函数,得通过函数名"math.sin"去用:
math.sin
现在把函数 math.sin 赋值给 oldSin,会出现下面的疑问:
math.sin.oldSin
可以这么去验证,用蓝色矩形表示一个新函数,将这个新函数赋值给 math.sin,然后检查 oldSin 是否也变化了:
事实上,在将 math.sin 的入口参数,从弧度改成角度时(这个例子参PIL第六章),有如下的定义方式:
do
  local oldSin = math.sin
  local k = math.pi/180
  math.sin = function (x)
    return oldSin(x*k)
  end
end
很明显,上图中,只有左边的情况才能和这里的代码吻合。

根据上面的经验,可以这么去理解 Lua 中函数的匿名性:把函数想象为一个功能块,这个功能块可以起任意名称。要使用这个功能块,就需要通过一个名称去访问它。如果把功能块的某个名称赋值给某个变量,这个变量会成为这个功能块(函数)的另一个名称罢了,和函数的其他名称毫无关系。

Java 中对象的匿名性

Java 中的对象(Object)也面临和前面 Lua 中类似的问题,很有趣,假定有一个对象,用蓝色椭圆表示,先命名为 a. 对应的代码和图示如下:
现在把这个 a 赋值给 b,会面临下面的选择:
object a b
类似前面 Lua 部分的做法,给 a 赋一个新的对象(青色的椭圆),然后检查 b 引用的是哪个椭圆就行了:
new a
现在通过代码来检验:
Object a = new Object();
Object b = a;

System. out.println(a);
System. out.println(b);
System. out.println(a.equals(b));

b = new Object();

System. out.println(a);
System. out.println(b);
System. out.println(a.equals(b));
某次执行的结果是:
java.lang.Object@602f892f
java.lang.Object@602f892f
true
java.lang.Object@602f892f
java.lang.Object@50d79dfe
false
可以看出,在 Java 中,实际用的是上面图中左边的选项。

根据前面的经验,可以这么去理解 Java 中对象的匿名性:对象(Object)本无名,并可任意命名,将名称赋值给某个变量后,这个变量就成为这个对象的另一个名称而已。

后记

在得到文中的理解后,感到很爽,它证实了体验不同语言的积极作用。
Lua 中 table 也有匿名性的特点,和这里比较类似,因此不打算赘述了。
文中有个瑕疵,就是两部分的图形颜色的顺序不一致,不整齐,不过做图比较麻烦,就不打算调整了。




Comments