《lua프로그래밍》 독서노트 제7장: 교체기와 범형for
7.1 교체기와closure
'교체기'는 집합의 모든 요소를 두루 훑어보는 메커니즘이다. Lua에서는 보통 교체기를 함수로 표시하고 함수를 한 번도 호출하지 않으면 집합의'다음'요소로 되돌아간다.closure는 교체기에 아주 좋은 지원을 제공합니다. 하나의closure 구조는 보통 두 가지 함수와 관련이 있습니다.closure 자체와closure를 만드는 공장 함수입니다.테이블의 각 요소의 값을 반환하는 간단한 반복기를 작성합니다.
function value(t)
local i = 0
return function() i = i + 1; return t[i] end
end
이 예에서value는 하나의 공장으로 폐쇄closure로 되돌아옵니다.이 반복기를 사용하여 다음 테이블을 반복합니다.
t = {10, 20, 30}
iter = value(t)
while true do
local element = iter()
if element == nil then break end
print(element)
end
그러나 범용 for를 사용하는 것은 더욱 간단하다. 이것은 바로 교체기를 위해 설계된 것이다.
t = {10, 20, 30}
for val in value(t) do
print(val)
end
좀 더 복잡한 예를 살펴보겠습니다.
function allwords()
local line = io.read()
local pos = 1
return function()
while line do
local s,e = string.find(line, "%w+", pos)
if s then
pos = e + 1
return string.sub(line, s, e)
else
line = io.read()
pos = 1
end
end
return nil
end
end
for word in allwords() do
print(word)
end
7.2 범용 for의 의미
앞에서 언급한 교체기는 모두 단점이 하나 있는데, 모든 새로운 순환에 closure를 만들어야 한다는 것이다.범용 for는 순환 과정 내부에 교체기 함수를 저장하는데, 실제로는 3개의 값을 저장한다. 하나는 교체기 함수, 하나는 고정 상태, 하나는 제어 변수이다.일반 for 구문은 다음과 같습니다.
for in <exp-list> do
< body >
end
do
local _f, _s, _var = < explist >
while true do
local var_1, ... var_n = _f(s, _var)
_var = var_1
if _var = nil then break end
end
end
우리가 간단한 교체기를 사용할 때, 공장은 하나의 교체기 함수만 되돌려주기 때문에, 고정 상태와 제어 변수는nil이다.
7.3 무상태 교체기
무상태 교체기란 자신이 어떤 상태도 보존하지 않는 교체기입니다. 매번 교체할 때마다 for순환은 고정된 상태와 제어 변수로 교체기 함수를 호출하여 다음 요소를 생성합니다.전형적인 예는 바로 ipairs다.ipairs는 다음과 같이 자체 구현됩니다.
local function iter(a, i)
i = i + 1
local v = a[i]
if v then return i, v end
end
function ipairs(a)
return iter, a, 0
end
7.4 복잡한 상태를 가진 교체기
동행 교체기는 많은 상태를 저장해야 하지만 for순환은 고정된 상태와 제어 변수만 제공합니다.간단한 해결 방법은 closure를 사용하거나, 교체기에 필요한 모든 상태를 하나의 테이블로 포장하여 고정된 상태에 저장하는 것이다.
local iterator
function allwords()
local state = {line = io.read(), pos = 1}
return iterator, state
end
function iterator(state)
while state.line do
local s, e = string.find(state.line, "%W+", state.pos)
if s then
state.pos = e + 1
return string.sub(state.line, s, e)
else
state.line = io.read()
state.pos = 1
end
end
return nil
end
가능한 한 무상태 교체기를 작성합니다. 그러면 모든 상태가 for 변수에 저장되며, 순환을 시작할 때 새로운 대상을 만들 필요가 없습니다.그렇지 않으면 closure를 사용해 보아야 합니다. 보통 한 closure가 실행하는 교체기가 한 테이블을 사용하는 교체기보다 효율적이기 때문입니다. 이것은 한 테이블이 한 테이블보다 값이 싸고, 그 다음에 '비국부적인 변수' 를 방문하는 것이 테이블 필드에 접근하는 것보다 빠르기 때문입니다.
7.5 진정한 교체기
실제로 상술한 교체기는 실제 교체를 하지 않았고 진정으로 교체를 하는 것은 for순환이다.그러나 교체기는 매번 교체에 성공한 후의 반환 값을 제공할 뿐'생성기'와 같다.또한 교체기를 만드는 방법은 교체기에서 실제 교체 작업을 하는 것이다.
function allwords(f)
for line in io.lines() do
for word in string.gmatch(line, "%W+") do
f(word)
end
end
end
두 종류의 교체기는 대체적으로 같은 비용을 부담하지만, 생성기 스타일의 교체기는 더욱 유연하다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.