0Pricing
Lua Academy · Lekcja

Współdzielone upvalues między domknięciami

Proszę poznać współdzielenie tego samego upvalue przez wiele domknięć i konsekwencje modyfikacji.

Współdzielone upvalues między domknięciami to bezpłatna lekcja Lua Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Lua Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Lua Academy zawiera 4 lekcji w sumie.

Współdzielenie tego samego upvalue

Dwa domknięcia zdefiniowane w tym samym zakresie mogą współdzielić dokładnie tę samą komórkę upvalue. Zmiany wykonane przez jedno z nich są widoczne dla drugiego.

local function makeGetterSetter()
  local value = 0
  local function get() return value end
  local function set(v) value = v end
  return get, set
end
local get, set = makeGetterSetter()
set(42)
print(get())  -- 42

Dlaczego dochodzi do współdzielenia

Lua nie kopiuje upvalues dla każdego domknięcia. Wszystkie domknięcia utworzone w tym samym bloku, wskazujące tę samą zmienną lokalną, współdzielą jedną komórkę upvalue.

Wzorzec obserwatora za pomocą współdzielonego upvalue

Współdzielone upvalue może pełnić funkcję magistrali komunikatów między wieloma domknięciami.

local count = 0
local inc = function() count = count + 1 end
local dec = function() count = count - 1 end
local get = function() return count end
inc(); inc(); dec()
print(get())  -- 1

Pułapka zmiennej pętli

W pętli numeric for każda iteracja tworzy nową lokalną zmienną pętli, dlatego domknięcia przechwytują niezależne upvalues.

local fns = {}
for i = 1, 3 do
  fns[i] = function() return i end
end
print(fns[1](), fns[2](), fns[3]())  -- 1 2 3 (each closure has its own i)

Pułapka zmiennej pętli while

W pętli while, jeśli domknięcie przechwytuje jedną zmieniającą się zmienną, wszystkie domknięcia współdzielą to samo upvalue i widzą wartość końcową.

local fns = {}
local i = 0
while i < 3 do
  i = i + 1
  fns[i] = function() return i end  -- all share same i!
end
print(fns[1]())  -- 3 (not 1!)

Przechwytywanie nowej zmiennej lokalnej

Aby przechwytywać niezależne wartości w pętli while, należy wprowadzić nową zmienną lokalną wewnątrz treści pętli.

local fns = {}
local i = 0
while i < 3 do
  i = i + 1
  local ci = i  -- new local per iteration
  fns[i] = function() return ci end
end
print(fns[1]())  -- 1, fns[2]() == 2

Wzorzec modułu ze współdzielonym stanem

Moduł może udostępniać wiele funkcji współdzielących prywatną tabelę stanu za pośrednictwem upvalues.

local function makeStack()
  local data = {}
  return {
    push = function(v) data[#data+1] = v end,
    pop  = function() local v = data[#data]; data[#data]=nil; return v end,
    size = function() return #data end,
  }
end

Aliasing i modyfikowanie

Należy zachować ostrożność: wszystkie domknięcia odwołujące się do tego samego upvalue natychmiast widzą tę samą zmianę. Jest to potężne rozwiązanie, ale może prowadzić do niezamierzonego powiązania.

Tożsamość upvalue

debug.upvalueid(f, n) zwraca unikalną tożsamość n-tego upvalue funkcji f. Dwa domknięcia z tym samym identyfikatorem upvalue współdzielą tę samą komórkę.

debug.upvaluejoin

debug.upvaluejoin(f1, n1, f2, n2) sprawia, że n-te upvalue funkcji f1 współdzieli tę samą komórkę co n-te upvalue funkcji f2. Jest to narzędzie niskopoziomowe przeznaczone do debugowania.

Praktyczne wzorce

  • Pary funkcji getter/setter współdzielące prywatną zmienną.
  • Licznik zdarzeń z funkcją reset udostępnioną przez wiele domknięć.
  • Stan modułu współdzielony przez kilka funkcji API.

Pytanie o współdzielone upvalue

Dwa domknięcia get i set są tworzone w tym samym zakresie i oba przechwytują value. Jeśli zostanie wywołane set(99), co zwróci get()?

Podsumowanie: współdzielone upvalues

Domknięcia w tym samym zakresie współdzielą komórki upvalues. Zmiany są natychmiast widoczne dla wszystkich współdzielących je domknięć. Jest to podstawa enkapsulacji i stanu modułów w Lua.

Często zadawane pytania

Czy lekcja „Współdzielone upvalues między domknięciami” jest bezpłatna?

Tak — pełny tekst „Współdzielone upvalues między domknięciami” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Lua Academy, przejdź na CoddyKit PRO. Kurs Lua Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Współdzielone upvalues między domknięciami”?

Proszę poznać współdzielenie tego samego upvalue przez wiele domknięć i konsekwencje modyfikacji. Ćwiczysz Lua Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Lua Academy?

Nie wymagamy żadnego doświadczenia. Lua Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Współdzielone upvalues między domknięciami”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Lua Academy?

Tak. Każda lekcja Lua Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Czym są upvalues?
  2. Współdzielone upvalues między domknięciami
  3. Funkcje fabrykujące i generatory
  4. Memoizacja za pomocą domknięć
← Powrót do Lua Academy