捕获具有多个允许类型/特征的块

问题描述:

是否可以在具有多个允许特征的方法内捕获块?捕获具有多个允许类型/特征的块

alias IoBlockFormatter = Severity, Time, String, String, IO -> Nil 
alias StringBlockFormatter = Severity, Time, String, String -> String 

class Formatter 
    def initialize(@io : IO, &@block : IoBlockFormatter | StringBlockFormatter) 
    end 
end 

在这个例子中,我定义两种不同类型的功能,我想,让我Formatter类可以接受是两种类型的块。我的第一次尝试尝试使用这两种类型的联合,但编译器抱怨期待函数类型,而不是两个Proc类型的联合。

expected block type to be a function type, not (Proc(Severity, Time, String, String, IO, Nil) | Proc(Severity, Time, String, String, String)) 

    def initialize(@io : IO, &@block : IoBlockFormatter | StringBlockFormatter) 

您不能让一个方法采用多个块类型,因为块是从方法签名中键入的,而不是其他方式。一旦找到正确的方法,块参数的类型将从yield中推导出来,带有未捕获的块,以及来自捕获参数中的&block的类型。您也不能有两个具有相同参数和块的重载,即使该块由于类似的原因而被不同地使用。

+0

当定义一个方法时,没有考虑块的类型签名是什么原因?天真地说,我认为它是函数类型签名的一部分,就像其他参数一样。 –

+0

因为当你传递一个块时,你不会给出参数的类型,你只需使用'| a,b,c |'。这意味着要计算出要调用的重载,您需要知道a,b和c的类型,但要键入它们,您需要知道您调用的是哪种方法。这是一个递归查找,因此不可能。 – RX14