全局与局部变量?

时间:2015-03-19 21:24:08

标签: ruby methods factorial

我想知道为什么我的代码在一个实例中工作但在另一个实例中不工作。它与局部变量和全局变量有关吗?

这有效:

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

4 个答案:

答案 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已经nilresult.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 * numnil.to_i等于0,因此这会将result设置为0以用于循环的后续迭代,并且正如您所做的那样。只需将结果值乘以0即可。