4

假设一个函数定义如下:

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 将作为字符串数组返回。

4

2 回答 2

10

这样的检查是不可能的,因为接受一个块(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
于 2016-08-28T12:43:17.700 回答
1

在您的具体情况下,我会推荐 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

于 2021-10-25T19:04:06.020 回答