跳至內容

捕獲區塊

區塊可以被捕獲並轉換為 Proc,它代表一段程式碼及其相關的上下文:閉包的資料。

要捕獲區塊,您必須將其指定為方法區塊參數,給它一個名稱並指定輸入和輸出類型。例如

def int_to_int(&block : Int32 -> Int32)
  block
end

proc = int_to_int { |x| x + 1 }
proc.call(1) # => 2

上述程式碼會捕獲傳遞給 int_to_int 的區塊,並將其儲存在 block 變數中,然後從方法中返回。proc 的類型是 Proc(Int32, Int32),這是一個接受單一 Int32 引數並返回 Int32 的函式。

這樣就可以將區塊儲存為回呼

class Model
  def on_save(&block)
    @on_save_callback = block
  end

  def save
    if callback = @on_save_callback
      callback.call
    end
  end
end

model = Model.new
model.on_save { puts "Saved!" }
model.save # prints "Saved!"

在上面的範例中,沒有指定 &block 的類型:這僅表示捕獲的區塊不接受任何引數,也不返回任何內容。

請注意,如果沒有指定返回類型,則不會從 proc 呼叫返回任何內容

def some_proc(&block : Int32 ->)
  block
end

proc = some_proc { |x| x + 1 }
proc.call(1) # => nil

若要返回某些內容,請指定返回類型或使用底線以允許任何返回類型

def some_proc(&block : Int32 -> _)
  block
end

proc = some_proc { |x| x + 1 }
proc.call(1) # 2

proc = some_proc { |x| x.to_s }
proc.call(1) # "1"

break 和 next

returnbreak 不能在捕獲的區塊內使用。可以使用 next,它會退出並給出捕獲區塊的值。

with ... yield

無法使用 with ... yield 更改捕獲區塊內的預設接收者。