根据元编程,对象中有 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 无法区分这是一个变量还是一个方法调用, 我倒是觉得引入了 @实例变量, 让编写一个类, 变的更直观, 更简单.