Ruby中能否声明块级变量?如何在块内定义变量i?
Ruby块中如何正确使用状态变量i
首先,你尝试的do |num, j; i = 0|语法是错误的——块的局部变量确实可以用;和参数分开声明,但不能直接在参数列表里赋值。而且就算写成do |num, j; i|,每次执行块时这个i都会是全新的局部变量,要是在块里初始化i = 0,那每次迭代i都会被重置,根本没法实现累加的效果。
你的需求是在迭代过程中保持i的状态,不用在块外声明的话,有两种更合适的写法:
方法1:使用inject(推荐)
inject可以帮你维护一个累加状态,每次迭代都会把上一次块返回的值作为下一次的状态变量:
nums.inject(0) do |i, (num, j)| if num != 0 nums[i], nums[j] = num, nums[i] i + 1 # 返回新的i值,供下一次迭代使用 else i # 不满足条件时,保持i不变 end end
方法2:使用each_with_object配合可变对象
因为Ruby的整数是不可变的,直接用each_with_object(0)的话,i +=1只会生成新的整数,没法更新原状态,所以可以用数组这类可变对象来存i的值:
nums.each_with_object([0]) do |(num, j), arr| i = arr[0] if num != 0 nums[i], nums[j] = num, nums[i] arr[0] += 1 # 修改数组里的值,保持状态 end end
当然,你最开始那种在块外声明i的写法是完全没问题的,Ruby的块是闭包,可以访问外部作用域的变量,只要你不介意这个i存在于块外的作用域里,这种写法反而更直观。
内容的提问来源于stack exchange,提问作者sweii
相关产品推荐
相关产品推荐

