'each ... do'和'do'有什么区别

时间:2019-08-01 07:50:08

标签: ruby

只是处理一些练习问题,但我对“做什么”到底能做什么感到困惑

root

此代码与

有什么区别
self.length.times do |i|

6 个答案:

答案 0 :(得分:3)

Ruby中的

do ... end代码块(或大多数等效的{ ... }块)是一项重要的语言功能,可让您将某些行为(即某些代码块)传递给方法。如果您了解Javascript,则可以将Ruby的块看作是匿名函数,这是一个第一近似值。

现在,当将一个块传递给each方法时,它将为枚举中的每个元素调用一次该块,并将当前元素w作为该块的第一个参数传递。

Integer#times方法也占用一个块。它将使用一个数字作为参数调用该块n次,从0开始计数到n - 1(其中n是您调用times方法的任何数字。因此,该区块将被准确地调用n次。

由于块是Ruby不可或缺的一部分,而Ruby随处可见,因此您应该尝试很好地了解它们的工作原理。如果您搜索“红宝石块”,就会在Google上找到很多指南和帖子。

答案 1 :(得分:1)

我想举几个例子。

假设self对象是Array

self_object = ['a', 'b', 'c']


使用前一个选项self_object.length.times do |i|,您将调用Array#length,后者返回整数3,然后在整数33.times)上调用Integer#times 。结果是:

self_object.length.times do |i|
  p i
end

# 0
# 1
# 2


使用最后一个选项,您只是在数组上调用Array#each,所以:

self_object.each do |i|
  p i
end

# "a"
# "b"
# "c"


each方法适用于以下对象(see docs):

  • ARGF,
  • 数组,
  • Dir,
  • 枚举器
  • Enumerator :: ArithmeticSequence,
  • Enumerator :: Chain
  • 哈希
  • IO
  • ObjectSpace :: WeakMap
  • 范围
  • 结构

答案 2 :(得分:1)

区别在于i的值。

["one", "two", "three"].length.times do |i|
  puts i
end

0
1
2

和另一个:

["one", "two", "three"].each do |i|
  puts i
end

one
two
three

如您所见,一个返回循环索引,另一个返回数组项。

答案 3 :(得分:0)

使用

{
  "private": true,
  "scripts": {
    "dev": "npm run development",
    "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "npm run development -- --watch",
    "watch-poll": "npm run watch -- --watch-poll",
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "prod": "npm run production",
    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "test": "cross-env NODE_ENV=test jest",
    "tdd": "npm run test -- --watch --notify"
  },
  "devDependencies": {
    "@coreui/coreui": "^2.0.4",
    "@fortawesome/fontawesome-svg-core": "^1.2.2",
    "@fortawesome/free-brands-svg-icons": "^5.2.0",
    "@fortawesome/free-regular-svg-icons": "^5.2.0",
    "@fortawesome/free-solid-svg-icons": "^5.2.0",
    "@vue/test-utils": "^1.0.0-beta.10",
    "axios": "^0.18",
    "babel-jest": "^22.1.0",
    "bootstrap": "^4.0.0",
    "cross-env": "^5.1",
    "jest": "^22.1.4",
    "jest-vue-preprocessor": "^1.3.1",
    "jquery": "^3.2",
    "laravel-mix": "^2.0",
    "lodash": "^4.17.5",
    "pace": "github:HubSpot/pace#v1.0.2",
    "perfect-scrollbar": "^1.4.0",
    "popper.js": "^1.12.4",
    "sweetalert2": "^7.0.7",
    "vue": "^2.5.7"
  },
  "jest": {
    "testURL": "http://localhost",
    "roots": [
      "<rootDir>/tests/Javascript/"
    ],
    "moduleNameMapper": {
      "^vue$": "vue/dist/vue.common.js"
    },
    "moduleFileExtensions": [
      "js",
      "vue"
    ],
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
      ".*\\.(vue)$": "<rootDir>/node_modules/jest-vue-preprocessor"
    }
  },
  "dependencies": {
    "bootstrap-datepicker": "^1.8.0",
    "clipboard": "^2.0.4",
    "datatables.net": "^1.10.19",
    "datatables.net-bs4": "^1.10.19",
    "datatables.net-scroller": "^2.0.0",
    "debounce": "^1.2.0",
    "jquery-datatables-checkboxes": "^1.2.11",
    "owl.carousel": "^2.3.4",
    "select2": "^4.0.6-rc.1"
  }
}

self.length.times do |i| 只是计算0到i之间的数字。

使用

self.length - 1

self.each do |i| 将使用i中每个元素的值。

答案 4 :(得分:0)

两者

self.each do |i|

self.length.times do |i|

不是有效的Ruby。

在Ruby do中,关键字是开始一个块的关键字。 必须后接end关键字,以结束一个块。 Here is a good article您可以阅读有关块的知识,以及它们与其他类似Ruby构造(例如Procs和Lambdas)的关系。

答案 5 :(得分:0)

我认为这实际上是如何工作的。

让我们有代码

# could be also defined as with_env_variable_set_to_hello(&block)
def with_env_variable_set_to_hello
   fail ArgumentError unless block_given?

   origin = ENV['MY_VARIABLE']
   ENV['MY_VARIABLE'] = 'hello'
   yield # runs block here
   ENV['MY_VARIABLE'] = origin
end

用法:

with_env_variable_set_to_hello do
   puts ENV['MY_VARIABLE'] # hello
end

有时候,您可以使用传递来阻止的参数,例如

items.each do |item|
  # do something
end

通过为yield(&block)提供参数来提供

def do_something
  yield 'arg1', :arg2, 3
end

用法:

do_something do |string, symbol, integer|
  puts string, symbol, integer # 'arg1' :arg2 3
end