while 트러스 : & while : 항상 nil을 반환합니다. 예 : 일반 재귀 정의가있는 경우 :
whileTrue: aBlock
^self value ifTrue: [self whileTrue: aBlock]
ifTrue : 자기 값이 false 인 경우 nil을 반환하고 그래서 값은 항상 nil을해야합니다. 이것은 컴파일러의 최적화에 반영됩니다. 원래 파란색 책 스몰 토크-80 V2 정의는
입니다
whileTrue: aBlock
"Evaluate the argument, aBlock, as long as the value
of the receiver is true. Ordinarily compiled in-line.
But could also be done in Smalltalk as follows"
^self value
ifTrue:
[aBlock value.
self whileTrue: aBlock]
그러니 그냥
BlockContext>>myWhileTrue: aBlock
| start |
start := thisContext pc.
self value ifFalse: [^nil ].
aBlock value.
thisContext pc: start
또는 귀하의 변경 ??
BlockContext>>myWhileTrue: aBlock
| start |
start := thisContext pc.
^self value ifTrue:
[aBlock value.
thisContext pc: start]
그러나 이러한 사고는 VM 모두 슬프게도
언젠가 스택의 상단이 :) 그러나
무엇이든 thisContext PC를 대신 다음 반복에 PC를 대답 만하지 않기 때문에 두 번째 반복 후 다음을 수행 작업 :
ContextPart methods for controlling
label
^{ pc. stackp }
goto: aLabel
"N.B. we *must* answer label so that the
top of stack is aLabel as it is when we send label"
pc := aLabel at: 1.
self stackp: (aLabel at: 2).
^aLabel
BlockContext>>myWhileTrue: aBlock
| label |
label := thisContext label.
self value ifFalse: [^nil].
aBlock value.
thisContext goto: label
BlockClosure>>myWhileTrue: aBlock
| label |
label := thisContext label.
^self value ifTrue:
[aBlock value.
thisContext goto: label]
당신은 항상 도움이, 덕분에 루카스 :) –
이 경우에는 문맥을 복원하는 것은 기본적으로 GOTO –
과 같습니다. 무한 반복없이 무한한 수의 구문없이 문맥을 재개하는 능력은 불가능한 것처럼 보인다. –