我不明白这种方法

时间:2016-12-08 19:41:44

标签: ruby

我是Ruby的初学者,我不明白这段代码在做什么,你能解释一下吗,拜托?

def a(n)
  s = 0
  for i in 0..n-1
    s += i
  end
  s
end

5 个答案:

答案 0 :(得分:4)

def定义了一种方法。可以使用方法在不同的值上运行相同的代码。例如,假设您想获得数字的平方:

def square(n)
  n * n
end

现在我可以用不同的值来做到这一点,我不必重复n * n

square(1) # => 1
square(2) # => 4
square(3) # => 9

=是一项任务。

s = 0基本上说,在名称s后面,现在有一个

0..n-1 - 构建一个范围,其中包含0n - 1之间的所有数字。例如:

puts (0..3).to_a
  # 0
  # 1
  # 2
  # 3

for为该范围的每个连续值分配i。它循环遍历所有值。首先i0,然后是1,然后是...... n - 1

s += is = s + i的简写。换句话说,在每次迭代时将s的现有值增加i

最后的s只是说方法(记住我们用def打开的内容)会返回s的值。换句话说 - 到目前为止我们累积的总和。

您可以在5分钟内完成编程课程。

答案 1 :(得分:2)

这个例子不是惯用的Ruby代码,即使它在语法上是有效的。 Ruby几乎不使用for构造,迭代器更灵活。如果你来自另一个语言背景,for是许多程序的支柱,那么这似乎很奇怪。

在任何情况下,程序都会分解为:

# Define a method called a which takes an argument n
def a(n)
  # Assign 0 to the local variable s
  s = 0

  # For each value i in the range 0 through n minus one...
  for i in 0..n-1
    # ...add that value to s.
    s += i
  end

  # The result of this method is s, the sum of those values.
  s
end

更多Ruby表达方式是使用times

def a(n)
  s = 0

  # Repeat this block n times, and in each iteration i will represent
  # a value in the range 0 to n-1 in order.
  n.times do |i|
    s += i
  end

  s
end

这只是针对for问题。代码已经更具可读性了,请注意,n.times 做某事do ... end块表示用于每次迭代的一大块代码。 Ruby块在一开始可能有点令人困惑,但理解它们对于在Ruby中有效是绝对必要的。

更进一步:

def a(n)
  # For each element i in the range 0 to n-1...
  (0..n-1).reduce |sum, i|
    # ...add i to the sum and use that as the sum in the next round.
    sum + i
  end
end

reduce方法是Ruby中的一个简单工具,如果有效使用它是非常有效的。它允许您快速旋转事物列表并将它们压缩为单个值,因此得名。它也被称为inject,它只是同一事物的别名。

您也可以使用简写:

def a(n)
  # For each element in the range 0 to n-1, combine them with +
  # and return that as the result of this method.
  (0..n-1).reduce(&:+)
end

此处&:+{ |a,b| a + b }的简写,&:x的缩写为{ |a,b| a.x(b) }

答案 2 :(得分:1)

方法 a(n)计算第一个 n 自然数的总和。

示例: 当n = 4时,则s = 0 + 1 + 2 + 3 = 6

答案 3 :(得分:1)

由于你是Ruby的初学者,让我们从小片开始。

@Test public void testSingletonAnotherThingNotInstantiatedTwiceByInjector() { //act AnotherThing first = injector.getInstance(AnotherThing.class); AnotherThing second = injector.getInstance(AnotherThing.class); //assert assertSame(first, second); } => [0,n-1]。例如。 0..n-1 => 0,1,2,3 => [0,3]

0..3 =>这是一个for循环。 for i in 0.. n-1遍历[0,n-1]。

is += i

相同

因此。方法s = s + i初始化a(n)然后在for循环中遍历[0,n - 1]和s = 0

在此方法结束时,有一个s = s + i。 Ruby省略了关键字s。所以你可以看到return

return s

相同
def a(n)
  s = 0
  for i in 0..n-1
    s += i
  end
  s
end

def a(n) s = 0 for i in 0..n-1 s = s + i end return s end = 0 + 1 + 2 + 3 = 6

希望这有用。

答案 4 :(得分:0)

让我们按符号去吧!

def a(n)

这是函数def inition的开始,您定义的函数a只需要一个参数n - 所有典型的软件内容。值得注意的是,您也可以def使用其他功能:

foo = "foo"
def foo.bar
  "bar"
end
foo.bar() # "bar"
"foo".bar # NoMethodError

下一行:

  s = 0

在这一行中,您既要声明变量s,又要将其初始值设置为0。也是典型的编程。

值得注意的是,整个表达式的值; s = 0,是赋值后s的值:

s = 0
r = t = s += 1 # You can think: r = (t = (s += 1) )
# r and t are now 1

下一行:

  for i in 0..n-1

这是一个循环;特别是for ... in ...循环。这个有点难以解压缩,但整个陈述基本上是:“对于0n-1之间的每个整数,将该数字分配给i,然后执行某些操作”。实际上,在Ruby中,编写此行的另一种方法是:

(0..n-1).each do |i|

此行与您的行完全相同。

对于单行循环,您可以使用{}代替doend

(0..n-1).each{|i| s += i }

此行和您的for循环完全相同。

(0..n-1)range。范围非常有趣!你可以用很多东西来组成一个范围,特别是时间:

(Time.now..Time.new(2017, 1, 1)) # Now, until Jan 1st in 2017

您还可以更改“步长”,以便代替每个整数,例如每1/10:

(0..5).step(0.1).to_a # [0.0, 0.1, 0.2, ...]

此外,您可以使范围排除最后一个值:

(0..5).to_a # [0, 1, 2, 3, 4, 5]
(0...5).to_a # [0, 1, 2, 3, 4]

下一行!

s += i

通常大声朗读“加 - 等于”。它实际上与:s = s + 1相同。 AFAIK,几乎Ruby中的每个操作员都可以这样配对:

s = 5
s -= 2 # 3
s *= 4 # 12
s /= 2 # 6
s %= 4 # 2
# etc

最后一行(我们将这些作为一组):

  end
  s
end

deffor启动的“块”(代码组)需要end,这就是您在此处所做的。

但也是!

Ruby中的所有东西都有价值。每个表达式都有一个值(包括赋值,如第2行所示)和每个代码块。 块的默认值是该块中最后一个表达式的值

对于你的函数,最后一个表达式只是s,所以表达式的值是s的值,毕竟说完了。这与以下内容完全相同:

  return s
end

对于循环,它更奇怪 - 它最终成为评估范围。

这个例子可能会更清楚:

n = 5
s = 0
x = for i in (0..n-1)
  s += i
end
# x is (0..4)

总结一下,另一种写函数的方法是:

def a(n)
  s = 0
  (0..n-1).each{ |i| s = s + i }
  return s
end

有问题吗?