15

私はRubyを初めて使用します。私は高階関数を可能にする多くのC#とJavaScriptを使用しており、通常はそれらを日常的に使用しています。

しかし、Rubyは私には少し奇妙に思えます。関数は次のeachようになります。

def each
    @items.each do |item|
        yield(item)
    end
end

items.each { |item| puts item }

それでも、Rubyは高階関数もある程度サポートしています。上記は次のように書き直すことができます。

def each(proc)
    @items.each do |item|
        proc.call item
    end
end

items.each -> (item) { puts item }        # Or...
items.each lambda { |item| puts item }

あるいは:

def each(&proc)
    @items.each do |item|
        proc.call item
    end
end

# No difference in syntax.
items.each { |item| puts item }

これは他のほとんどの言語と同等であり、ほんの数文字長くなっています。ブロックを明示的に渡す代わりに、すべてがを使用しているようyieldです。

yieldそれ自体はクレイジーで、魔法のようで、神秘的です。結局のところ、それは呼び出しの発信元に行き、呼び出しの直後にブロックをつかみます。これは奇妙で不自然に思えますが、他の言語でこの機能が類似していることを私は知りません。

それで、どうしたのyield

4

4 に答える 4

14

収量はシンタックスシュガー

この収量の例:

def do_something_for_each(array)
  array.each do |el|
    yield(el)
  end
end

次の構文シュガーです。

def do_something_for_each(array, &block)
  array.each do |el|
    block.call(el)
  end
end

好きな構文を選んで、それを使いこなしてください。

于 2013-01-14T01:25:42.757 に答える
6

Yieldはオブジェクトをメソッドのブロックに渡します

[歩留まりは]通話の発信元に移動し、通話の直後にブロックを取得します。

あまり。yieldブロックに引数を渡します。「ブロックをつかむ」ことも、それを使って何かをすることもありません。言い換えれば、これは:

def foo; yield self; end
foo { |x| x.inspect }                                       
# => "main"

ここでyieldは、メソッドに渡されるブロックに引数を渡す以外に何もしていませんfoo。すべてのRubyメソッドは、ブロックが実際に必須である場合を除いて、オプションのブロックをサポートします。したがって、唯一の「魔法」は、メソッドシグネチャの一部として明示的に宣言されていない場合でも、言語がブロックの受け渡しを許可することです。

さらなる例

この暗黙の署名の動作を確認するには、次のことを考慮してください。

def foo; puts block_given?; end
foo { |x| x.inspect }

これは「true」を出力し、メソッドnilから期待される戻り値であるを返します。puts

もちろん、yieldブロックがないと何も起こりません。例えば:

def foo; end
foo { |x| x.inspect }
# => nil
于 2013-01-14T01:11:58.100 に答える
4

の利点の 1 つは、 (like ) とyieldも使用できることです。他の言語では、 forでは を使用する必要があり、 forでは例外を (ab) 使用する必要がある場合があります。この種の操作のサポートが組み込まれている方が、間違いなく優れています。nextcontinuebreaknextreturnbreak

于 2013-01-14T00:22:10.303 に答える