Crystal 如何检查函数内部是否给出了块参数

Crystal How to check if the block argument is given inside the function

假设一个函数定义如下:

def composition(text : String, k : Int32) : Array(String)
  kmers = Array(String).new
  (0 .. text.size - k).each do |i|
    kmers << text[i, k]
    yield text[i, k]
  end
  return kmers
end

如何检查函数内部是否给出了块参数? 如果给出 block 参数,将产生 kmers。如果未给出,kmers 将作为字符串数组返回。

这样的检查是不可能的,因为接受块的方法(在任何地方使用 yield)已经有一个签名需要它。但这也意味着您不需要支票。如果你想让它成为可选的,只需像这样制作 2 个方法:

# if you want to be explicit (makes no difference, this method requires a block):
# def composition(text : String, k : Int32, &block)
def composition(text : String, k : Int32)
  (0 .. text.size - k).each do |i|
    yield text[i, k]
  end
end

# and the non block option
def composition(text : String, k : Int32) : Array(String)
  kmers = [] of String
  composition(text, k) do |s|
    kmers << s
  end
  return kmers
end

根据您的具体情况,我会推荐 Oleh 的答案。但是,这里有一个更通用的解决方案,可让您确定是否已通过一个块:

def composition(text, k, &block : String ->)
  composition(text, k, block)
end

def composition(text, k, block : (String ->)? = nil)
  kmers = [] of String
  (0 .. text.size - k).each do |i|
    s = text[i, k]
    if block
      block.call s
    else
      kmers << s
    end
  end
  kmers
end

(有关 Proc 语法的更多信息,请参阅 https://crystal-lang.org/reference/syntax_and_semantics/type_grammar.html#proc