全局变量还是局部变量?
Global vs local variables?
我想知道为什么我的代码在一个实例中有效,但在另一个实例中却无效。跟局部变量和全局变量有关系吗?
这个有效:
def factorial num
result = 1
while (num > 1)
result = result * num
num -= 1
end
puts result
end
这行不通:
result = 1
def factorial num
while (num > 1)
result = result.to_i * num
num -= 1
end
puts result
end
方法定义中的所有内容都无法从其他地方看到局部变量。这听起来很奇怪,但有两种解决方法:
result = 1
number = 10
def factorial(num,result_value)
while (num > 1)
result_value = result_value.to_i * num
num -= 1
end
puts result_value
end
factorial(number, result)
将结果作为参数传递。这是处理方法的好方法,因为它不允许您从方法内部更改结果的值。这可能看起来没什么大不了的,但是 "pure methods" 随着代码大小的增加,这样会变得非常有价值。
这是做同样事情的 "dirty" 或非纯粹的方式:
@result = 1
def factorial(num)
while (num > 1)
@result = @result.to_i * num
num -= 1
end
puts @result
end
在变量名前加上 @
允许其范围扩展到在其范围之外定义的方法。随着代码复杂性的增加,这会成为一个问题。
随机个人意见:尽管 Ruby 不要求您将括号放在方法定义旁边,但您始终应该这样做。它使代码更加明确和易于阅读。随心所欲 ;)
您可以通过在所有 result
前加上一个 $ 符号来进行试验,使其成为全球性的。在实例变量前加上 @ 会产生一个实例变量,这也很有趣。旁注:puts
打印和 returns nil
,所以你的方法 returns nil
.
result = 1 # line 1
def factorial num
while (num > 1)
result = result.to_i * num
num -= 1
end
puts result
end
在此代码中,factorial
不知道第 1 行中的 result
变量。
当 Ruby 在您的方法中找到 result = result.to_i * num
时,它将首先将 nil
分配给 result
。然后Ruby会尝试运行result.to_i * num
。因为 result
已经是 nil
,所以 result.to_i
等于 0.
这是另一个例子:
def foo
a = a
puts "#{a.class}"
end
foo #NilClass
在 不起作用 版本中,您分配给 1 的 result
变量在 factorial
方法中不可见。
现在 Ruby 中可能出现意外行为,如果您尝试分配一个变量并且在分配的右侧引用同一个变量,如果该变量没有value 然后它被视为 nil
而不是引发错误。所以当你执行
时第一次循环
result = result.to_i * num
它等同于 result = nil.to_i * num
并且 nil.to_i
等于 0 所以这将设置 result
为 0 对于循环的后续迭代,因为你只是乘以结果的值保持为 0。
我想知道为什么我的代码在一个实例中有效,但在另一个实例中却无效。跟局部变量和全局变量有关系吗?
这个有效:
def factorial num
result = 1
while (num > 1)
result = result * num
num -= 1
end
puts result
end
这行不通:
result = 1
def factorial num
while (num > 1)
result = result.to_i * num
num -= 1
end
puts result
end
方法定义中的所有内容都无法从其他地方看到局部变量。这听起来很奇怪,但有两种解决方法:
result = 1
number = 10
def factorial(num,result_value)
while (num > 1)
result_value = result_value.to_i * num
num -= 1
end
puts result_value
end
factorial(number, result)
将结果作为参数传递。这是处理方法的好方法,因为它不允许您从方法内部更改结果的值。这可能看起来没什么大不了的,但是 "pure methods" 随着代码大小的增加,这样会变得非常有价值。
这是做同样事情的 "dirty" 或非纯粹的方式:
@result = 1
def factorial(num)
while (num > 1)
@result = @result.to_i * num
num -= 1
end
puts @result
end
在变量名前加上 @
允许其范围扩展到在其范围之外定义的方法。随着代码复杂性的增加,这会成为一个问题。
随机个人意见:尽管 Ruby 不要求您将括号放在方法定义旁边,但您始终应该这样做。它使代码更加明确和易于阅读。随心所欲 ;)
您可以通过在所有 result
前加上一个 $ 符号来进行试验,使其成为全球性的。在实例变量前加上 @ 会产生一个实例变量,这也很有趣。旁注:puts
打印和 returns nil
,所以你的方法 returns nil
.
result = 1 # line 1
def factorial num
while (num > 1)
result = result.to_i * num
num -= 1
end
puts result
end
在此代码中,factorial
不知道第 1 行中的 result
变量。
当 Ruby 在您的方法中找到 result = result.to_i * num
时,它将首先将 nil
分配给 result
。然后Ruby会尝试运行result.to_i * num
。因为 result
已经是 nil
,所以 result.to_i
等于 0.
这是另一个例子:
def foo
a = a
puts "#{a.class}"
end
foo #NilClass
在 不起作用 版本中,您分配给 1 的 result
变量在 factorial
方法中不可见。
现在 Ruby 中可能出现意外行为,如果您尝试分配一个变量并且在分配的右侧引用同一个变量,如果该变量没有value 然后它被视为 nil
而不是引发错误。所以当你执行
result = result.to_i * num
它等同于 result = nil.to_i * num
并且 nil.to_i
等于 0 所以这将设置 result
为 0 对于循环的后续迭代,因为你只是乘以结果的值保持为 0。