我想知道为什么我的代码在一个实例中工作但在另一个实例中不工作。它与局部变量和全局变量有关吗?
这有效:
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
答案 0 :(得分:0)
方法定义中的所有内容都无法从其他位置查看局部变量。这听起来很奇怪,但是有两种方法可以解决它:
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)
将结果作为参数传递。这是处理该方法的一种很好的方法,因为它不允许您在方法中更改结果的值。这可能看起来不是什么大不了的事,但是"纯粹的方法"这样随着代码增加的大小变得非常有价值。
这是"脏"或者做出同样事情的非纯粹方式:
@result = 1
def factorial(num)
while (num > 1)
@result = @result.to_i * num
num -= 1
end
puts @result
end
将@
放在变量名前面允许其范围扩展到在其范围之外定义的方法。随着代码复杂性的增加,这成为一个问题。
随机个人意见:尽管Ruby并不要求你将括号放在方法定义的旁边,但你总是应该这样做。它使代码更加明确,更易于阅读。跟随你的心脏;)
答案 1 :(得分:0)
您可以通过在所有result
前加上$符号进行试验,使其成为全局。在@前面加上一个实例变量,也很有趣。旁注:puts
打印并返回nil
,因此您的方法会返回nil
。
答案 2 :(得分:0)
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
答案 3 :(得分:0)
在不工作版本中,您在result
方法中看不到的factorial
变量是不可见的。< / p>
现在Ruby中可能存在一个意外的行为,如果你试图分配一个变量,并且在赋值的右侧引用相同的变量,如果该变量还没有值,那么它被视为nil
而不是引发错误。所以当你执行
result = result.to_i * num
它等同于result = nil.to_i * num
和nil.to_i
等于0,因此这会将result
设置为0以用于循环的后续迭代,并且正如您所做的那样。只需将结果值乘以0即可。