Zacznijmy od postulowania, że pamięć jest zdecydowanie (dziesiątki, setki, a nawet tysiące razy) bardziej powszechna niż wszystkie inne zasoby razem wzięte. Każda pojedyncza zmienna, obiekt, członek obiektu potrzebuje pewnej pamięci przydzielonej do niej i zwolnionej później. Dla każdego otwieranego pliku tworzysz dziesiątki do milionów obiektów do przechowywania danych wyciągniętych z pliku. Każdy strumień TCP idzie w parze z nieograniczoną liczbą tymczasowych ciągów bajtów utworzonych do zapisu w strumieniu. Czy jesteśmy na tej samej stronie tutaj? Wspaniały.
Aby RAII działało (nawet jeśli masz gotowe inteligentne wskaźniki dla każdego przypadku użycia pod słońcem), musisz uzyskać prawo własności . Musisz przeanalizować, kto powinien być właścicielem tego lub innego obiektu, a kto nie, a kiedy własność powinna zostać przeniesiona z A do B. Jasne, możesz użyć współwłasności do wszystkiego , ale wtedy będziesz emulować GC za pomocą inteligentnych wskaźników. W tym momencie staje się znacznie łatwiejsze i szybsze wbudowanie GC w język.
Wyrzucanie elementów bezużytecznych uwalnia cię od troski o najczęściej używany zasób - pamięć. Jasne, nadal musisz podjąć tę samą decyzję w odniesieniu do innych zasobów, ale są one znacznie mniej powszechne (patrz wyżej), a skomplikowane (np. Wspólne) własności również są mniej powszechne. Obciążenie psychiczne jest znacznie zmniejszone.
Teraz nazywasz niektóre wady, aby wszystkie wartości były usuwane. Jednak integracja zarówno bezpiecznego dla pamięci GC, jak i typów wartości z RAII w jednym języku jest niezwykle trudna, więc może lepiej jest zmusić te kompromisy za pomocą innych środków?
Utrata determinizmu okazuje się w praktyce nie taka zła, ponieważ wpływa tylko na żywotność obiektu deterministycznego . Jak opisano w następnym akapicie, większość zasobów (oprócz pamięci, która jest obfita i może być przetwarzana raczej leniwie), nie jest zobowiązana do życia obiektów w tych językach. Istnieje kilka innych przypadków użycia, ale z mojego doświadczenia są rzadkie.
Drugi punkt, ręczne zarządzanie zasobami, jest obecnie rozwiązywany za pomocą instrukcji, która wykonuje czyszczenie na podstawie zakresu, ale nie łączy tego czyszczenia z czasem życia obiektu (a zatem nie wchodzi w interakcje z GC i bezpieczeństwem pamięci). To jest using
w C #, with
w Pythonie, try
-with-resources w najnowszych wersjach Java.