根据元编程,对象中有 4 个东西:引用 实例变量 object_id 状态,方法存在于类中,这样才可以共享实例方法,难道类变量也存在与类中吗?
类变量作用类似 Java 的静态变量。 能够为该类对象以及子类对象访问,不可控风险较大。特别是在顶级对象上下文中(名称为 Main 的 Object 对象)下定义类变量,几乎所有对象都能访问该类变量。的确不太推荐使用,
嗨,首先你的回复,根本不是楼主讨论的问题。其次,你的回复也是错的。前言不大后语,你那些演示代码,从头到尾,都在演示类实例变量,根本没有类变量的影子。他们谈的类变量是@@类变量。
#4 楼 @Anleb
我发现大家都一样。从一开始,我就在思考类变量到底在那里,也没有个确定的结果,双飞燕上也没有介绍,我不赞成你的理解,类对象是 Class 的实例,你如果说类变量存在于 Class 中,那么即使存在继承关系的两个类,不可能在子类中修改父类的类变量。你说的那个东西,应该是类的实例变量
才是。
@@类变量,我的理解,他就是类对象指向的那个堆中 (定义了实例方法的那一片内存区域) 的一个特殊的变量而已。你就可以理解为一个整个继承体系内的一个全局变量
就是了,反正应该是个特殊的 dd, 我也无法确定到底是如何实现的。只要知道怎么用就行了。
实现方式,存储在 klass 的 iv_tbl 中:
1508 VALUE
1509 rb_cvar_get(klass, id)
1510 VALUE klass;
1511 ID id;
1512 {
1513 VALUE value;
1514 VALUE tmp;
1515
1516 tmp = klass;
1517 while (tmp) {
1518 if (RCLASS(tmp)->iv_tbl) {
1519 if (st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
1520 if (RTEST(ruby_verbose)) {
1521 cvar_override_check(id, tmp);
1522 }
1523 return value;
1524 }
1525 }
1526 tmp = RCLASS(tmp)->super;
1527 }
1528
1529 rb_name_error(id,"uninitialized class variable %s in %s",
1530 rb_id2name(id), rb_class2name(klass));
1531 return Qnil; /* not reached */
1532 }
(variable.c)
#10 楼 @zw963 你有 QQ 啥吗,我看你也是学习狂,我们交流下,我今天有个问题,我发你连接http://ruby-china.org/topics/4588
我觉得就是为了要实现这个怪怪的功能而设计。牵一发而动全身,整个类中只有一份共享,这就是类变量的目的。既然 Matz 一定要搞这么个东西出来,自然有特殊的场合,类变量是无法替代的。
其实我了解楼主还有@fsword的想法,他们 (包括我) 都是属于被 Ruby 洗脑了。凡事儿都要使用对象这个概念解释一番。这在 Ruby 语言之上是没错的。不过非要把这个想法加到 Ruby 的实现上,就会是这样。之前我也曾经用对象的思维方式来考虑方法的定义呢。不过很显然,脑子想破也想不通的。
@fsword 类变量自然属于类,类中的 iv_tble 存放类变量正好。另一种实现可以采用全局表,但全局表查询会存在问题,也不符合设计模式中全局变量的使用。
你讲的这个 type is-a object 理论,是你说的那个 Simula-67 里面的吗?
你说的这个成员变量和类变量是两码事吧,我觉得按照你的想法,其实是指的类应该有类的实例变量
.
你讲的这个 type is-a object 理论,是你说的那个 Simula-67 里面的吗?
自那以后,有类型系统的语言,类型系统一般来说都是这么设计的。
首先要定义两个特殊的东西,object
, type
,接着定义 is-a
,
因为,* is-a
object
,于是
is-a
objectis-a
object又,A is-a
B => B is-a
type,所以
is-a
typeis-a
type你说的这个成员变量和类变量是两码事吧,我觉得按照你的想法,其实是指的类应该有
类的实例变量
.
你把类给特殊化了。从上面的定义出发,你所以为的类变量
,就是一个普通的成员变量,无非这个object
恰好是一个类而已。
P.S. 在这里不区分class
和type
,instance
和object
看你介绍,看得晕晕乎乎,不过觉得很有意思。
又,typeof(Anything) is-a type,所以
type is-a type object is-a type
我怎么觉得应该是
又,typeof(Anything) is-a type,所以
typeof(type) is-a type typeof(object) is-a type
或者:
因此,typeof(Anything) is-a object,所以
type is-a object.
而,object is-a type, 这应该是在特殊情况下,才满足。
你把类给特殊化了。根据定义,类,就是一个普通的 object。你所以为的类变量,只不过就是一个成员变量,无非这个 object 恰好是一个类而已. P.S. 在这里不区分 class 和 type,instance 和 object
你讲的这个成员变量到底是什么东西?我怎么觉得这个概念非常像 C++ 里面的说法。C++ 里面的成员变量的确是在类当中被定义的。其实咱们谈的那个@@类变量
, 其实的确和你说的成员变量挺像的。不过我现在想确认一点,在 C++ 中,一个类的两个不同实例,他们的成员变量彼此之间有影响吗?我记得好像沒有影响,即,C++中, 每个类的实例都有自己单独的成员变量值.
, 如果是这样的话,咱们谈的还不是一个东西。
你说的成员变量只是一个相对于 Ruby 的类实例变量
不同定义方式而已。而这里谈的类变量
, 他就是类自己的变量。所有的子孙共享同一个变量,整个继承体系只有这么一个,而且这个变量只在定义类变量的那个类中
存在唯一的一份拷贝。
你讲的这个成员变量到底是什么东西?
成员变量:instance.member
。
但 Ruby 的语法导致这里很复杂。因为 Ruby 里调用一个函数,不需要括号。这导致了instance.X
实际上就是instance.X()
。所以必须引入@X
这种方式去取得成员变量。
在 C++ 中,一个类的两个不同实例,他们的成员变量彼此之间有影响吗
你忘了加了static
之后,就变成类的成员变量,而不是实例的成员变量。
我怎么觉得应该是
又,typeof(Anything) is-a type,所以 typeof(type) is-a type typeof(object) is-a type
我改一下,现在应该清楚一点了。
嗯。现在看起来清楚了。呵呵。牛啊,这花花肠子绕的。
我的确忘记有 static 这回事儿了。那就没错了,Ruby 中的类变量,就是 C++ 中加 static 的成员变量。
跑题一下:
类变量
和类的实例变量
是有区别的。
1.类的实例变量
就和普通变量一样,存在对象里。只不过这个类是 Class,因为所有的类都是 Class 的实例。这就是 Ruby 里说的一切都是对象。
2.类变量
我的理解是:类范围内的全局变量,他可以被实例和类本身访问/修改,可以被继承。
有关引入@成员变量,我记得当时学 Ruby 时还是有心得的。主要原因是 Ruby 无法区分这是一个变量还是一个方法调用,我倒是觉得引入了@实例变量,让编写一个类,变的更直观,更简单。