9

ダフのデバイスは、次のようなフォールスルー スイッチとループの構造を組み合わせて使用​​することがわかっています。

send(to, from, count)
register short *to, *from;
register count;
{
    register n = (count + 7) / 8;
    switch (count % 8) {
    case 0: do { *to = *from++;
    case 7:      *to = *from++;
    case 6:      *to = *from++;
    case 5:      *to = *from++;
    case 4:      *to = *from++;
    case 3:      *to = *from++;
    case 2:      *to = *from++;
    case 1:      *to = *from++;
            } while (--n > 0);
    }
}

現在、Swif 2.1 では、Swift のドキュメントで読んでいるように、 switch-case 制御フローに暗黙的にフォールスルーはありません。

暗黙的なフォールスルーなし

C および Objective-C の switch ステートメントとは対照的に、Swift の switch ステートメントは、デフォルトでは、各ケースの最下部から次のケースに移行しません。代わりに、明示的な break ステートメントを必要とせずに、最初に一致する switch ケースが完了するとすぐに、switch ステートメント全体が実行を終了します。これにより、switch ステートメントが C よりも安全で使いやすくなり、誤って複数の switch ケースを実行することを回避できます。

ここで、Swift でフォールスルーの副作用を明示的に持つフォールスルー句があるとします。

フォールスルー

Swift の switch ステートメントは、各ケースの最下部から次のケースに移行しません。代わりに、最初に一致するケースが完了するとすぐに、switch ステートメント全体が実行を完了します。対照的に、C では、フォールスルーを防ぐために、すべての switch ケースの最後に明示的な break ステートメントを挿入する必要があります。デフォルトのフォールスルーを回避することは、Swift の switch ステートメントが C の対応するステートメントよりもはるかに簡潔で予測可能であることを意味し、したがって複数の switch ケースを誤って実行することを回避します。

それはかなり似ています:

let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += " a prime number, and also"
    fallthrough
default:
    description += " an integer."
}
print(description)
// prints "The number 5 is a prime number, and also an integer."

ウィキペディアが私たちに思い出させるように、デバイスは問題から出てくることを考慮して

A straightforward code to copy items from an array to a memory-mapped output register might look like this:
do {                          /* count > 0 assumed */
    *to = *from++;            /* "to" pointer is NOT incremented, see explanation below */
} while(--count > 0);

Swift でのダフのデバイスの正確な実装はどれですか?

これは単なる言語とコーディングの問題であり、実際の Swift アプリケーションに適用することを意図したものではありません。

4

2 に答える 2

3

Duffs デバイスは、最適化以上のものです。https://research.swtch.com/duffを見ると、このメカニズムを使用してコルーチンを実装することについての議論があります (Duff 氏からのコメントについては、段落 8 を参照してください)。

この機能を使用せずに移植可能なコルーチン パッケージを作成しようとすると、. jmpbuf エントリをアセンブリまたは再書き込みすることになります [どちらも移植性がありません]。

go や swift などの最新の言語は、C よりもメモリ モデルが制限されているため、この種のメカニズム (私は想像します) は、あらゆる種類の追跡の問題を引き起こします。clang,gcc のラムダのようなブロック構造でさえ、最終的にはスレッド ローカル ストレージと絡み合ってしまい、単純なアプリケーションに固執しない限り、あらゆる種類の混乱を引き起こす可能性があります。

于 2019-07-09T23:14:52.997 に答える