2016-08-24 40 views
7

Używam Lua 5.3.Jak znaleźć `f`, który sprawia, że` pcall (pcall, f) `zwraca` false` w Lua?

Czytanie "Programowanie w Lua 3rd edition", wszedłem do ćwiczenia prosząc mnie, żebym znalazł f, który sprawia, że ​​pcall(pcall, f) powraca false. Myślę, że jest to równoważne z podnoszeniem błędu przez pcall(f). Ale wydaje się, że użycie tego nie wystarczy. Na przykład niech f = nil i nic złego się nie dzieje.

Jednak znalazłem w Internecie, że pozwala f = (function() end)() załatwia sprawę. Ale nie rozumiem, dlaczego. Tutaj f jest tylko wartością zwracaną (która jest nil) funkcji function() end w prawo?

Odpowiedz

6

To nie działa

> f = (function() end)() 
> pcall(pcall, f) 
true false attempt to call a nil value 

ale to robi:

> pcall(pcall,(function() end)()) 
false bad argument #1 to 'pcall' (value expected) 

Różnica polega na tym, że (function() end)() nie zwraca żadnej wartości, która różni się od powrotu nil. Funkcje napisane w Lua nie mogą tego rozróżnić, ale pcall jest napisane w C i może uczynić to rozróżnienie. (Innymi przykładami są print i type.)

Zauważ, że ten zachowuje się zgodnie z oczekiwaniami (odpowiednik pierwszej próbie):

> pcall(pcall,(function() return nil end)()) 
true false attempt to call a nil value 
+0

Dzięki. Czyli coś nie jest warte zauważenia? –

+0

"Funkcje napisane w Lua nie mogą tego odróżnić": jest to coś, co 'select ('#', ...)' może dostarczyć, czyż nie jest: '(funkcja (...) print (select ('# ', ...)) end) ((function() end)()) '? –

+0

@PaulKulchenko, tak, ale potrzebujesz pomocy z funkcji bibliotecznej, takiej jak 'wybierz'. – lhf

2

Wynika to z tego, że kod, do którego dzwonisz, jest równoważny z pcall(pcall), a nie z pcall(pcall, nil). Funkcja nie zwraca niczego; W niektórych kontekstach jest to dostosowane do nil, ale nadal jest inne niż nil w innych kontekstach (tak jak w tym przykładzie).