2

私は Smalltalk を独学しようとしています。チュートリアルには、while ループのこの例があります。

|i| 
i:=5. 
[i >0] whileTrue:[ 
 Transcript show: ((i*2) asString) ; cr. 
 i:=i-1. 
].

私が理解しているように、whileTrue は BlockClosure に送信されるメッセージであり、受信側が true である限り、引数として指定された BlockClosure を実行するように受信側 BlockClosure に指示します。

BlockClosure が応答する whileTrue メッセージは、Smalltalk で while ループ構造なしでどのように実装されていますか? それとも、ランタイムが書かれている言語で実装されていますか?

4

3 に答える 3

8

私の VisualWorks イメージでは、再帰を使用して実行されます。

whileTrue: aBlock

   ^自己値
      真であれば:
      [ブロック値。
      [自己値] whileTrue: [aBlock 値]]

ただし、レシーバーと引数の両方がリテラル ブロックである場合、コンパイラは #whileTrue: 呼び出しをインライン化するという注意事項もあります。したがって、ほとんどの場合、#whileTrue も考慮することができます。これは、構文的にはメッセージ送信のように見えますが、内部でさまざまなバイトコードに最適化されている「魔法の」メッセージの 1 つです。

于 2009-01-28T23:47:10.037 に答える
0

すでに述べたように、コンパイラは私が知っているすべての実装でチートとインラインを行います。したがって、メソッドが通常の状況で存在する必要は実際にはなく、通常は呼び出されません。ただし、このメソッドは、実際にコンパイラを使用せずに動的に生成されたコード構造を実行または解釈する場合に役立つことがあります。

ちなみに、Smalltalk言語標準(実際には存在しない)は実装に末尾呼び出しを排除することを強制しないため(たとえば、Schemeとは対照的に)、VWでの再帰的な実装は実行や解釈にはあまり役立ちません(コンパイラーチートが標準化されていない限り)。

再帰のない代替手段は次のようになります。

whileTrue:aBlock
    self value ifFalse:[^ nil].
    aBlock value.
    thisContext restart
于 2010-08-22T08:20:36.570 に答える
0

このフォーラムによれば、whileTrue は実際のメッセージではありません。

于 2009-01-27T22:27:19.497 に答える