2017-10-07 10 views
2

複数の許可されたシグネチャを持つメソッド内でブロックをキャプチャすることは可能ですか?この例では複数の許可されたタイプ/シグネチャを持つブロックのキャプチャ

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 

、私は2つの異なる機能タイプを定義しています、と私は私のFormatterクラスは、いずれのタイプであることを受け入れることができますブロックを許可したいです。この最初の試みは、2つの型の和集合を使用しようとしますが、コンパイラは、2つのProc型の和集合ではなくFunction型を期待していると不平を言っています。

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) 

答えて

3

あなたはブロックがメソッドシグネチャ、周りにいない他の方法から入力されるように、1つの方法は、複数のブロックタイプを取ることはできません。正しい方法が見つかると、ブロック引数のタイプは、キャプチャされていないブロックのあるyieldと、キャプチャされた引数のタイプ&blockから推定されます。同様の理由でブロックが異なって使用されたとしても、同じ引数とブロックを持つ2つのオーバーロードを持つことはできません。

+0

メソッドの定義時にブロックの型シグネチャが考慮されない理由は何ですか?他の引数と同じように、関数の型シグネチャの一部であるように、私にはまったく見えません。 –

+0

ブロックを渡すときに引数の型を指定しないので、 '| a、b、c |'だけを使用します。つまり、どのオーバーロードを呼び出すかを決めるには、a、b、cのタイプを知る必要がありますが、タイプするには、呼び出す方法を知る必要があります。これは再帰的なルックアップであり、したがって不可能です。 – RX14

関連する問題