Ruby中变量、实例变量、类变量之解惑
ruby中变量分:
局部变量
全局变量
实例变量
类变量
这四种,往往会造成刚入Ruby大门的程序员迷惑。
各自的定义如下:
- 局部:x = 5
- 全局:$x = 5
- 实例:@x = 5
- 类变:@@x = 5
解释:
局部变量,也就是基本的变量,在变量定义的相同地方使用;可以定义顶层局部变量,但在类、方法、模块定义内仍无法访问该变量;局部变量不可以在内部类、子类中访问;类中的方法不可以访问该类中定义的局部变量(平级);在声明局部变量的类、模块、方法内,局部变量从声明该变量处开始生效,随类、方法、模块的定义结束而结束。
全局变量,如未初始化而引用,值为nil;作用范围,从定义时开始,直到程序结束;尽量少用,因为他会造成模块间的强耦合。
实例变量,在对象中定义,属于特定的对象(Private);可以在类或子类的方法中引用实例变量;若引用尚未被初始化的实例变量的话,其值为nil。
ruby语言是一门动态语言,因此Ruby的实例变量无须声明,每个实例变量都是在第一次出现时动态加入对象。因此,Ruby的实例变量通常在方法中定义类声明——当在方法里声明实例变量时,该实例变量实际上属于该方法所在类的实例,而不是属于该方法。 作用域:self。
注意:实例变量通常在方法中定义;实例变量的访问范围总是:private,即在类定义内对实例变量的赋值和读取没有限制;在类外访问实例变量时,则可以通过方法来访问;实例变量永远都不能暴露为public,只能通过类方法(类名.方法名)暴露;模块中定义实例变量,可以混入该模块中的类中,即模块中的类可以共享模块中定义的实例变量。
类变量(class),在类中定义,被一个类的所有实例对象共享,也可以被类方法访问到;类变量是私有的,在类外无法直接访问,你只能通过实例方法和类方法去访问它;和全局变量,实例变量不同,类变量在使用前必须初始化。类变量用于存储类的全局信息,它只属于类,不同与类实例变量,每一个类的对象都有一份数据。 类变量是可以被继承的,也就是说如果我们派生一个子类,那么在子类中是可以访问父类的类变量的。类变量在访问前必须赋值。子类和父类共享一份数据,对一个类的修改会反映到另一个类中。作用域:在类或模块内的任意位置都可以访问此类或模块中定义的常量,在这之外,可以通过域作用符(::)访问,内部直接使用,外部用::。
注意:一个类、其子类、它们的实例:的同名类变量共享了同一块内存区域(都引用了同一个变量);模块中定义的类变量,可以混入该模块中的类,即模块中的类可以共享模块中定义的类变量。
类的类实例变量是在类的类方法中或方法外边(不能在实例方法中,那是类的实例变量)以@开头定义的变量,这样定义的变量值属于类对象本身,不能够被子类继承。如果要定义需要和子类共享的类全局数据,使用类变量;但是如果要定义仅供类本身使用的类全局数据可以使用类实例变量。还有一点需要注意的是,和类变量不同的是类实例变量不要求访问前必须赋值,不赋值它的值就是nil。
简单说就是实例变量属于每一个对象自己,而类变量被所有该类的对象共享。
类变量是静态的,实例变量是动态的。类变量只有一个,实例变量的数量取决于类实例的数量。
Ruby 变量并没有内在类型。作为一种动态解析执行的语言,其变量类型只在其执行期决定,我们也因此能改变变量所持有对象的类型。
类变量与常量区别:
1、类变量可以重复赋值;常量重复赋值时发出警告(不是错误);
2、类变量默认是protected的,不能在类外部直接引用;(可在继承类中以用或赋值);
类变量与实例变量区别:
1、在类范围内定义的类变量,可以在该类的方法中访问;而实例变量则不行;
2、类变量可在子类中引用或赋值,但实例变量可在类范围内直接引用或赋值;