赞 | 2 |
VIP | 143 |
好人卡 | 1 |
积分 | 1 |
经验 | 216792 |
最后登录 | 2019-10-10 |
在线时间 | 24 小时 |
Lv1.梦旅人
- 梦石
- 0
- 星屑
- 61
- 在线时间
- 24 小时
- 注册时间
- 2008-8-5
- 帖子
- 1924
|
本帖最后由 紫苏 于 2009-10-21 00:25 编辑
其实叫“实变量”容易引起歧义,比如用惯了 Pascal 的人可能还以为是在说 Real 型的浮点变量,最好称之为“实例变量”~这个可以参考:
http://rpg.blue/viewthread.php?tid=124591
至于局部变量,F1 里面的说法也不太准确……局部变量当然不一定都是在 def ... end 中的,只要是由 ASCII 字符中大写字母 [A-Z] 以外的有效字符打头的标示符,在任何地方被首次赋值定义都会被认为是局部变量~
一个局部变量会在第一次被赋予一个值时动态地被创建,但是其作用域却是静态地决定为直接包围它的代码块,也就是方法定义(def ... end)、类定义(class ... end)、模块定义(module ...end)以及顶层的程序的其中一个。举个例子:- t = Thread.new {
- a = 4
- Thread.stop
- p a # 线程内部定义的局部变量
- }
- a = 0
- module M
- a = 1
- class C
- a = 2
- def self.fn
- a = 3
- p a # 函数定义内部的局部变量 => 3
- end
- fn
- p a # 类定义内部的局部变量 => 2
- end
- p a # 模块定义内部的局部变量 => 1
- end
- p a # 顶层定义的局部变量 => 0
- t.run # => 4
复制代码 相同名称的局部变量如果分别是在不同的上下文中定义的,那么它们的本身也就是不同的变量,指向不同的值,这就是作用域的区别~
比较特殊的情况就是线程的局部变量,如果一个局部变量是在线程中首次赋值定义的,那么它的作用域就在这个线程中,并且独立于外部的局部变量;如果同名的局部变量在线程外就已经被赋值过了,那么线程将会继承这个外部的局部变量,换句话说就是这个局部变量仍然是外部的那个变量,而不是局部于线程的变量
至于你说的 for ... end、while ... end 和 if ... else ... end,这个是可以被包含在 def ... end 等上述的五种代码块中的,并且即便它是在这些控制块里首次赋值定义的局部变量,其作用域还是外层的上述五种代码块之一,比如:- def fn
- while true
- if true
- for i in 0..0
- begin
- a = 99
- end
- end
- end
- break
- end
- p a # => 99
- end
- fn
复制代码 a 在所有控制语句的外部仍然是可见的,这一点和其它很多语言就不一样了 |
|