动态常量赋值 main.rb:6: Ruby

Dynamic constant assignment main.rb:6: Ruby

我在循环中命名变量时遇到该错误。该方法的要点是打印数组中唯一具有唯一奇偶校验的元素的索引位置。例如,该方法应该为以下输入数组打印“3”,因为它是唯一的奇数,其他所有都是偶数:[2, 4, 6, 3, 8, 10]。更具体地说,它向下面的 "Odd" 和 "Even" 变量指出错误 ("main.rb:7: dynamic constant assignment Odd = numbers[i] % 2 == 1")。

  def test(numbers)
  i=1
  countOdd = 0
  countEven = 0
  Odd = numbers[i] % 2 == 1
  Even = numbers[i] % 2 == 0

  while i < numbers.length
    if Odd
      countOdd += 1
      else countEven +=1
      end
    i+=1
  end

  if countEven == 1
  print Odd.index
  else print Even.index
  end
end

当您在 Ruby 中定义一个大写变量时,它是一个 常量 - 这是一种特殊的变量, 不允许这样做更改值(好吧,从技术上讲,您可以使用 const_set 更改它,但这在这里并不重要)。

由于此限制,Ruby 不允许 您在函数内更改常量。它假定该函数将被多次调用,这将导致常量更改值,正如我刚才提到的那样是非法的。

所以,快速修复,只需将 OddEven 替换为小写版本 oddeven。这样它们就是常规变量而不是常量。

以上代码可以 return 使用内置的数组方法轻松实现:

even_numbers = numbers.select(&:even?)
odd_numbers = numbers.select(&:odd?)

则偶数为even_numbers.count,同样odd_numbers.count

第一个奇数索引将是numbers.find_index(odd_numbers.first)

对于常量,您可以将过程分配给常量: Odd = Proc.new{ |n| n%2 == 1 } 然后像这样调用常量:Odd.call(10) #=> false,同样你可以为偶数定义一个过程。

这里发生的事情是每次方法被调用时,常量都会被重新定义,从而具有一个新值,但常量意味着保存一个不会改变的值,这就是错误的原因。

另请注意您的方法中的以下条件:

if Odd
  then do something
....

实际上并不正确。一旦常量拥有一个值,那么它将在执行期间具有该值。所以在执行 Odd = some_integer % 2 == 1 之后, Odd 常量将始终为真或假。并且不会在您的 if 条件下重新执行 some_integer % 2 == 1。但是如果你把它变成一个 proc 或 lamda,它会重新计算,因为它就像你在调用一个方法一样。

[注意] 但是在你的方法中做 Odd = Proc.new{ |n| n%2 == 1 } 仍然会给你同样的错误 dynamic constant assignment Odd = Proc.new { |n| numbers[n] % ... 因为每次方法运行时代码仍然会重新执行,每次都会给出不同的常量值.因此,通过将 Odd = Proc.new{ |n| n%2 == 1 } 定义放在方法之外然后执行 if Odd.call(i) 它会工作得很好。