Jeśli ma zamknięcia, czy mogę założyć, że mogę tam użyć wielu silnych technik stylu funkcjonalnego?Czy Smalltalk ma zamknięcia?
Odpowiedz
Tak, Smalltalk ma zamknięcia. Poniższy kod tworzy zamknięcie zwracającą sumę dwóch argumentów:
sum := [ :a :b | a + b ].
zamknięcia są obiekty, które mogą być instancja, mijały się i manipulować. Aby ocenić zamknięcie wysyłaniu value
, value:
, value:value:
...
sum value: 1 value: 2.
Zamknięcia są wyraźnie stosowane w kolekcjach iteracyjne, filtr, Mapa, ... wszystkie wartości kolekcji:
aCollection select: [ :each | each isOdd ].
aCollection inject: 0 into: [ :each :result | each + result ].
Ponadto, są one wykorzystywane do struktur kontrolnych jak pętle:
[ iterator hasNext ]
whileTrue: [ iterator next ].
1 to: 10 do: [ :each | ... ].
także warunkowe są realizowane za pomocą zamknięć:
condition
ifTrue: [ do this ]
ifFalse: [ do that ]
Pharo je ma:
wszystkie maszyny wirtualne mają wsparcie zamknięcie wymagane najnowsze obrazy
makeAdder := [ :x | [ :y | x + y ]].
add2 := makeAdder value: 2.
add2 value: 3.
Zwraca 5
.
jednak zauważyć, że
makeCounter := [ :init | [ init := init + 1. init ]].
nie zadziała (Cannot store into ->init …
), jak (na przykład) w CL:
CL-USER> ((lambda (init) (lambda() (incf init))) 0)
#<COMPILED-LEXICAL-CLOSURE #xC7A495E>
CL-USER> (funcall *)
1
CL-USER> (funcall **)
2
CL-USER> (funcall ***)
3
Jeśli się nie mylę, to używane do pracy przed wprowadzono nowy kompilator zamknięcia. Nie jestem pewien, dlaczego nie działa z nowym kompilatorem.
Argumenty bloku i metody są tylko do odczytu w Smalltalk. Niektóre starsze kompilatory nie sprawdzały jednak poprawnie pod kątem argumentów blokowych. –
Dzięki za wyjaśnienia, Lukas! – danlei
Ale możesz użyć bloku lokalnego, takiego jak ten: makeCounter: = [: init | | liczyć | count: = init. [count: = count + 1. count]]. (makeCounter wartość: 3) wartość; wartość –
- 1. HttpWebRequest nie ma metody zamknięcia?
- 2. Czy mamy zamknięcia w C++?
- 3. Parsowanie RDF w Smalltalk
- 4. Smalltalk i IoC
- 5. Czy przeprowadzanie sesji zamknięcia transakcji?
- 6. Gdzie jest Archiwum Smalltalk?
- 7. Pharo Smalltalk i mySql
- 8. Niespójności w smalltalk
- 9. Squeak Smalltalk: pętla Gra
- 10. Nadklasa Smalltalk kontra metaklasa?
- 11. Ciąg do Integer Smalltalk
- 12. Zmienne inicjalizacyjne Smalltalk
- 13. Utrwalanie danych w Smalltalk/Seaside
- 14. Śledzenie zamknięcia
- 15. Różnice między Smalltalk i python?
- 16. Czy można dokonać rekurencyjnego zamknięcia w Rust?
- 17. Delegowanie Smalltalk/przechowywanie selektorów wiadomości
- 18. Kontrola wersji dla Smalltalk/Seaside?
- 19. Czy możliwe jest rozszerzenie pojedynczego obiektu w Smalltalk
- 20. Czy można uruchamiać skrypty Smalltalk z wiersza poleceń?
- 21. Jak zainstalować wtyczkę smalltalk pisk?
- 22. Nie można przedłużyć zamknięcia w Swift?
- 23. Identyfikator foreach i zamknięcia
- 24. Recusive zamknięcia w JavaScript
- 25. Obrazy lub pliki w GNU Smalltalk?
- 26. Rozwijanie interfejsów użytkownika w GNU/Smalltalk
- 27. Zamknięcia nad __class__
- 28. Mieszanina zamknięcia() i zamknięciaNow()
- 29. Zamknięcia w Pythonie
- 30. przechodniów python krotek zamknięcia
Twój pierwszy przykład przyjmuje tylko parametry dostarczone przez komunikat 'value: value:', ale twój przykład 'whileTrue:' ma bloki, które używają zmiennej 'iterator', która jest zdefiniowana poza blokiem. Czy jedno jest lambdą, a drugie zamknięciem, czy też nie ma różnicy w Smalltalk? – quamrana
@quamrana: Nie ma żadnej widocznej różnicy. Większość wdrożeń Smalltalk optymalizuje ich obiekty zamykające w zależności od użycia zmiennych zewnętrznych. Wszystkie zamknięcia rozumieją te same wiadomości, więc dla ciebie jako programisty nie ma różnicy. –