<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 20\. Proc,Lambda 和塊 如果你了解某些編程語言,則可能聽說過閉包。 Proc 和 Blocks 是類似的事情。 你可以采用一段代碼,將其粘貼在`do` `end`塊之間,并將其分配給變量。 該變量包含一段代碼,可以像對象一樣進行操作并傳遞。 Proc 就像一個函數,但是它是一個對象。 讓我們看一個例子來了解什么是 Proc。 在文本編輯器中輸入程序 [proc.rb](code/proc.rb) 并執行。 ```rb #!/usr/bin/ruby # proc.rb say_hello = Proc.new do puts "Hello world!" end say_hello.call say_hello.call ``` 這就是輸出的樣子 ```rb Hello world! Hello world! ``` 現在讓我們遍歷代碼以理解它。 看一下以下幾行 ```rb say_hello = Proc.new do puts "Hello world!" end ``` 在這種情況下,你將使用單個 Ruby 語句`puts “Hello World!”`,并將其放在 do 和 end 之間。 通過將`Proc.new`附加在`do`(該塊的開始)之前,可以使此代碼成為 Proc。 你正在將 Proc 對象分配給名為`say_hello`的變量。 現在`say_hello`可以看作是包含一個程序的東西。 現在如何調用或執行代碼? 當我們需要調用名為`say_hello`的 Proc 片段時,我們編寫以下命令 ```rb say_hello.call ``` 在 [proc.rb](code/proc.rb) 中,我們兩次調用`say_hello`,因此得到兩個`Hello World!`作為輸出。 ### 20.1。 傳遞參數 像函數一樣,你可以將參數傳遞給 Proc。 要查看其工作方式,請鍵入程序 [proc_hello_you.rb](code/proc_hello_you.rb) 并執行它。 ```rb #!/usr/bin/ruby # proc_hello_you.rb hello_you = Proc.new do |name| puts "Hello #{name}" end hello_you.call "Peter" hello_you.call "Quater" ``` 執行后,程序將提供以下輸出。 ```rb Hello Peter Hello Quater ``` 看一下這段代碼 ```rb hello_you = Proc.new do |name| puts "Hello #{name}" end ``` 在上面的程序中。 請注意,我們在`do`關鍵字之后捕獲了一些東西,通過給`do |name|``我們將已傳遞到`Proc`塊的內容放入名為`name`的變量中。 現在,可以在 Proc 塊中的任何位置使用此變量來執行某些操作。 在`puts "Hello #{name}"`中,我們打印`Hello`,后跟傳遞的參數`name`。 因此,我們編寫了一個 Proc,可以接受傳遞給它的某些東西。 我們如何調用并傳遞一些東西? 好吧,請注意結尾處的語句,看看第一個,它說 ```rb hello_you.call "Peter" ``` `hello_you.call`調用要執行的 Proc 代碼。 我們將字符串`“Peter”`傳遞給 Proc,將該字符串復制到 Proc 中的變量`name`中,因此得到輸出`Hello Peter`。 當 Ruby 解釋器遇到`hello_you.call "Quarter"`時,它以類似的方式打印`Hello Quater`。 ### 20.2。 將 Proc 傳遞給方法 就像任何對象一樣,我們可以將 Proc 傳遞給方法。 看看下面的代碼( [proc_to_method.rb](code/proc_to_method.rb) )。 研究,編碼并執行 ```rb #!/usr/bin/ruby # proc_to_method.rb # An exampleof passing a proc to method def execute_proc some_proc some_proc.call end say_hello = Proc.new do puts "Hello world!" end execute_proc say_hello ``` 這就是輸出的樣子。 ```rb Hello world! ``` 現在讓我們分析`execute_proc`功能的代碼,其代碼如下 ```rb def execute_proc some_proc some_proc.call end ``` 我們接受一個稱為`some_proc`的參數,我們將其假定為 Proc。 然后,我們使用其自己的`call`方法執行該函數,即在函數中,我們僅使用`some_proc.call`對其進行調用,以執行傳遞的 Proc。 如果你看一下接下來的幾行,我們將創建一個名為`say_hello`的 Proc ```rb say_hello = Proc.new do puts "Hello world!" end ``` 我們在`say_hello` Proc 中所做的只是打印`Hello world!`。 現在我們調用方法`execute_proc`,并在下面的代碼段中傳遞`say_hello` ```rb execute_proc say_hello ``` 通過 Proc 之后,它將復制到`some_proc`參數,并且在執行或調用`some_proc`時,將忠實地打印`Hello world!`。 ### 20.3。 從函數返回 Proc 我之前寫過,Proc 可以被視為對象。 實際上,Proc 是一個對象。 我們可以將其傳遞給我們在上一節中看到的函數,現在我們可以看到一個從函數返回 Proc 的示例。 仔細閱讀下面給出的代碼( [proc_returning_it.rb](code/proc_returning_it.rb) )。 ```rb #!/usr/bin/ruby # proc_returning_it.rb # Function that returns a proc def return_proc Proc.new do |name| puts "The length of your name is #{name.length}" end end name_length = return_proc name_length.call "A.K.Karthikeyan" ``` 執行后,程序將拋出以下輸出 ```rb The length of your name is 15 ``` 查看功能`return_proc`。 在其中,我們創建一個新的 Proc,它接受一個名為`name`的參數。 假設名稱是一個字符串,我們只需打印其長度即可。 現在考慮此函數之后的代碼,如下所示: ```rb name_length = return_proc name_length.call "A.K.Karthikeyan" ``` 在第一行`name_length = return_proc`中,`name_length`被分配了`return_proc`方法返回的內容。 在這種情況下,由于`Proc.new`是`return_proc`方法中的最后一個語句/塊,因此它返回一個新的 Proc,該 Proc 被分配給`name_proc`。 因此,`name_proc`現在可以接受參數。 我們現在要做的就是先叫`name_proc`,然后叫`name` ```rb name_length.call "A.K.Karthikeyan" ``` 因此,`name_length`接受`name`作為參數,計算其長度并打印。 因此,此示例表明可以從函數返回 Proc。 ### 20.4。 過程和數組 現在讓我們看看如何將 Proc 與數組配合使用以對其進行過濾。 看下面的程序 [proc_and_array.rb](code/proc_and_array.rb) 。 在其中我們聲明了一個名為`get_proc`的 Proc,它帶有一個參數`num`。 在 Proc 中,如果`num`的偶數由以下語句`num unless num % 2 == 0`確保,則返回`num`。 運行程序并記下輸出。 ```rb # proc_and_array.rb get_odd = Proc.new do |num| num unless num % 2 == 0 end numbers = [1,2,3,4,5,6,7,8] p numbers.collect(&get_odd) p numbers.select(&get_odd) p numbers.map(&get_odd) ``` 輸出量 ```rb [1, nil, 3, nil, 5, nil, 7, nil] [1, 3, 5, 7] [1, nil, 3, nil, 5, nil, 7, nil] ``` 現在讓我們考慮以下三個語句 ```rb p numbers.collect(&get_odd) p numbers.select(&get_odd) p numbers.map(&get_odd) ``` 在其中,我們只考慮第一行`p numbers.collect(&get_odd)`,因此我們在變量`numbers`中存儲了一個數字數組,在`numbers`中調用了`collect`,將參數`&get_odd`傳遞給了它。 `&&lt;name_of_proc&gt;`將為數組中的每個元素調用 Proc,Proc 返回的所有內容將被收集到一個新數組中。 `p`確保將值打印出來供我們驗證。 如果仔細觀察,`p numbers.collect(&get_odd)`和`p numbers.map(&get_odd)`都會返回其中包含`nil`值的數組,而 select 過濾掉`nil`并返回剩余的值。 #### 20.4.1。 拉姆達 Lambda 就像 Procs。 期望兩個幾乎沒有區別。 我將在這里解釋其中一個,另外一個將在[第二個區別](#_the_second_difference)部分中說明。 好吧,現在看一個小程序 ```rb # lambda.rb print_hello = lambda do puts "Hello World!" end print_hello.call ``` Output ```rb Hello World! ``` 要了解該程序的工作原理,請閱讀 Proc,Lambda 和 Blocks。 ### 20.5。 將參數傳遞給 Lambda 執行以下程序。 ```rb # lambda_passing_argment.rb odd_or_even = lambda do |num| if num % 2 == 0 puts "#{num} is even" else puts "#{num} is odd" end end odd_or_even.call 7 odd_or_even.call 8 ``` Output ```rb 7 is odd 8 is even ``` 要了解其工作方式,請參見本章的[傳遞參數](#_passing_parameters)部分。 ### 20.6。 具有函數的 Proc 和 Lambda 好的,Proc 和 Lambda 有什么區別。 它們之間有兩個主要區別,這是第一個。 在下面的示例[中,calling_proc_and_lambda_in_function.rb](code/calling_proc_and_lambda_in_function.rb) 我們具有兩個函數,即`calling_lambda`和`calling_proc`,請在你的計算機上鍵入并運行此文件 ```rb # calling_proc_and_lambda_in_function.rb def calling_lambda puts "Started calling_lambda" some_lambda = lambda{ return "In Lambda" } puts some_lambda.call puts "Finished calling_lambda function" end def calling_proc puts "Started calling_proc" some_proc = Proc.new { return "In Proc" } puts some_proc.call puts "In calling_proc function" end calling_lambda calling_proc ``` Output ```rb Started calling_lambda In Lambda Finished calling_lambda function Started calling_proc ``` 你將看到如上所示的輸出。 因此,讓我們繼續執行它。 首先調用`calling_lambda`功能時,程序將通過執行`puts "Started calling_lambda"`打印`Started calling_lambda`。 接下來,我們定義一個新的 lambda `some_lambda`,并使用以下幾行代碼進行調用 ```rb some_lambda = lambda{ return "In Lambda" } puts some_lambda.call ``` 因此,當調用`some_lambda`時,它將返回`"In Lambda”`,該行將在第`puts some_lambda.call`行中打印。 然后執行函數`puts "Finished calling_lambda function"`中的最終語句,為我們提供以下輸出 ```rb Started calling_lambda In Lambda Finished calling_lambda function ``` 函數完成時。 接下來,我們調用函數`calling_proc`,我們希望它的行為類似于`call_lambda`,但事實并非如此! 那會怎樣呢? 從輸出中我們只知道`puts "Started calling_proc"`被執行了,之后呢? 好吧,請看下一行`some_proc = Proc.new { return "In Proc" }`,注意它有一個 return 語句。 當在函數中調用 Proc 并具有 return 語句時,它將終止該函數并返回 return 的值,就好像函數本身正在返回它一樣! 而 lambda 不會這樣做。 即使在函數中調用的 lambda 且被調用的 lambda 具有 return 語句,它也會在控件被調用后將控件傳遞給函數的下一行,而在 proc 調用中則不然,它只是退出返回自身函數的函數 重視價值(因為該功能很難返回)。 ### 20.7。 第二個區別 在上一節中,我寫了 Proc 和 Lambda 之間的一個區別,讓我們在這里看到第二個區別。 查看下面的代碼(在 irb 中執行)。 ```rb >> lambda = -> (x) { x.to_s } => #<Proc:0x00000001f65b70@(irb):1 (lambda)> >> lambda.call ArgumentError: wrong number of arguments (0 for 1) from (irb):1:in `block in irb_binding' from (irb):2:in `call' from (irb):2 from /home//karthikeyan.ak/.rvm/rubies/ruby-2.1.3/bin/irb:11:in `<main>' ``` 我已經使用 irb 來演示該示例。 在上面的代碼中,我們在以下語句`lambda = -&gt; (x) { x.to_s }`中定義了一個 Lambda,現在我們可以使用以下語句 lambda.call 對其進行調用,如你所見,因為我們有一個參數`x`,并且沒有傳遞任何內容給 Lambda 引發異常并對此進行抱怨。 現在讓我們嘗試一下 ```rb >> proc = Proc.new { |x| x.to_s} => #<Proc:0x00000001a17470@(irb):3> >> proc.call => "" ``` 因此,如你在上面看到的那樣,是否應將參數傳遞給 Proc,如果不傳遞參數,則在不提供參數的情況下調用 Proc,Proc 不會抱怨,而是將其視為`nil`。 &lt;sup class="footnote"&gt;[ [49](#_footnotedef_49 "View footnote.") ]&lt;/sup&gt; ### 20.8。 Lambda 和數組 執行以下程序 ```rb # lambda_and_array.rb get_odd = lambda do |num| num unless num%2 == 0 end numbers = [1,2,3,4,5,6,7,8] p numbers.collect(&get_odd) p numbers.select(&get_odd) p numbers.map(&get_odd) ``` Output ```rb [1, nil, 3, nil, 5, nil, 7, nil] [1, 3, 5, 7] [1, nil, 3, nil, 5, nil, 7, nil] ``` 要了解其工作原理,請閱讀本章的 [Proc 和數組](#_proc_and_arrays)部分。 #### 20.8.1。 塊和功能 我們已經看到了 Procs 以及如何將它們傳遞給方法和函數。 現在讓我們看一下塊以及如何將它們傳遞給函數。 鍵入示例 [blocks_in_methods.rb](code/blocks_in_methods.rb) 并執行它 ```rb # blocks_in_methods.rb def some_method *args, &block p args block.call end some_method 1, 3, 5, 7 do puts "boom thata" end ``` Output ```rb [1, 3, 5, 7] boom thata ``` 現在讓我們看一下代碼。 在代碼中,我們在以下行`def some_method *args, &block`中定義了一個名為`some_method`的方法。 請注意,我們正在接受`*args`中的所有參數,并且有一個名為`&block`的新名稱將被包含在代碼塊中。 你可以將&塊替換為其他變量,例如`&a`或`&something`或任何你喜歡的變量。 現在,忘記功能主體中的內容。 現在讓我們看一下函數的調用,如下所示 ```rb some_method 1, 3, 5, 7 do puts "boom thata" end ``` 因此,我們調用`some_method`并傳遞參數`1, 3, 5, 7`。 這將以數組形式存儲在`*args` &lt;sup class="footnote"&gt;[ [50](#_footnotedef_50 "View footnote.") ]&lt;/sup&gt; 變量中。 現在看到以`do`開頭和以`end`結尾,在這兩者之間,你可以具有任意數量的語句,換句話說,它是一個代碼塊。 我們只有一個聲明`puts "boom thata"`,就是這樣。 此代碼塊將放入`&block`變量。 現在在 some_method 中注意以下語句 ```rb def some_method *args, &block p args block.call end ``` 我們僅使用`block.call`而不是`&block.call`來調用該塊,這一點很重要。 當我們在塊上使用`call`方法時,該塊將被執行,并且輸出`“boom thata”`被打印出來。 現在讓我們看另一個例子,我們可以將變量傳遞給塊調用。 輸入以下示例并執行。 ```rb # blocks_in_methods_1.rb def some_method *args, &block p args block.call 7 end some_method 1, 3, 5, 7 do |number| puts "boom thata\n" * number end ``` Output ```rb [1, 3, 5, 7] boom thata boom thata boom thata boom thata boom thata boom thata boom thata ``` 請注意,在`some_method`定義中,我們已使用`block.call 7`調用了 Block,數字 7 到哪里去了? 好吧,看下面幾行 ```rb some_method 1, 3, 5, 7 do |number| puts "boom thata\n" * number end ``` 之后,我們使用`|number|`捕獲傳遞的變量,因此 7 被存儲在`number`中。 在塊內,我們將`"boom thata\n"`乘以`number`并打印出來。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看