Lua 튜토리얼 (5): 교체기와 일반 for
Lua에서, 교체기는 보통 함수로, 매번 함수를 호출할 때마다, 즉 집합의 '다음' 요소를 되돌려줍니다.모든 교체기는 매번 성공적으로 호출될 때마다 상태를 유지해야만 그것이 있는 위치와 다음에 반복될 때의 위치를 알 수 있다.이 점에서 Lua에서 closure 메커니즘은 이 문제에 대해 언어적 보장을 제공하는데 다음과 같은 예를 들 수 있다.
function values(t)
local i = 0
return function()
i = i + 1
return t[i]
end
end
t = {10, 20, 30}
it = values(t)
while true do
local element = it()
if element == nil then
break
end
print(element)
end
-- foreach ( for)
t2 = {15, 25, 35}
for element in values(t2) do
print(element)
end
-- :
--10
--20
--30
--15
--25
--35
위의 응용 예시를 보면while 방식에 비해 범형for 방식은 더욱 뚜렷한 실현 논리를 제공했다.루아는 내부에 교체기 함수를 저장하고, 교체할 때마다 이 은밀한 내부 교체기를 호출하여 교체기가 nil로 돌아올 때까지 순환을 끝내기 때문이다.
2. 범용 for의 의미:
상기 예시된 교체기는 순환할 때마다 새로운closure 변수를 만들어야 한다는 뚜렷한 단점이 있습니다. 그렇지 않으면 첫 번째 교체가 성공한 후에 이closure를 새로운 for 순환에 사용하면 바로 종료됩니다.
여기서 우리는 먼저 Lua 중범형(for)의 메커니즘을 상세하게 설명한 다음에 무상태 교체기의 예를 제시하여 우리의 이해를 편리하게 한다.만약 우리의 교체기가 무상태 교체기로 실현된다면, 매번의 범용 (for) 을 위해 새로운 교체기 변수를 다시 설명할 필요가 없다.범용(for)의 구문은 다음과 같습니다.
for in do
end
이해하기 편리하도록, 우리는 실제 응용에서 일반적으로 하나의 표현식 (expr) 만을 포함하기 때문에, 간단하게 보면, 이 설명은 표현식 목록이 아니라 하나의 표현식만 포함할 것이다.지금 우리는 먼저 표현식의 원형과 실례를 제시한다. 예를 들어 다음과 같다.
function ipairs2(a)
return iter,a,0
end
이 함수는 3개의 값을 되돌려줍니다. 첫 번째는 실제 교체기 함수 변수이고, 두 번째는 고정 대상입니다. 여기서 우리는 반복되는 용기로 이해할 수 있습니다. 세 번째 변수는iter () 함수를 호출할 때 전달되는 초기 값입니다.
다음은 iter () 함수의 실현을 살펴보자. 예를 들어
local function iter(a, i)
i = i + 1
local v = a[i]
if v then
return i, v
else
return nil, nil
end
end
교체기 함수iter () 에서 두 개의 값을 되돌려줍니다. 각각 테이블의 키와value에 대응합니다. 그 중에서 키 (되돌려주는 i) 가 nil이면 범용 (for) 은 이번 교체가 끝났다고 생각할 것입니다.다음은 실제 사용 사례를 살펴보겠습니다. 예를 들어 다음과 같습니다.
function ipairs2(a)
return iter,a,0
end
local function iter(a, i)
i = i + 1
local v = a[i]
if v then
return i, v
else
return nil, nil
end
end
a = {"one","two","three"}
for k,v in ipairs2(a) do
print(k, v)
end
-- :
--1 one
--2 two
--3 three
이 예의 범용 (for) 쓰기 방법은while 순환을 기반으로 하는 다음과 같은 방식으로 전개될 수 있습니다.
local function iter(a, i)
i = i + 1
local v = a[i]
if v then
return i, v
else
return nil, nil
end
end
function ipairs2(a)
return iter,a,0
end
a = {"one","two","three"}
do
local _it,_s,_var = ipairs2(a)
while true do
local var_1,var_2 = _it(_s,_var)
_var = var_1
if _var == nil then -- , nil。
break
end
print(var_1,var_2)
end
end
-- 。
3. 무상태 교체기의 예:
이곳의 예는 체인 테이블을 옮겨다니는 교체기를 실현할 것이다.
local function getnext(list, node) -- 。
if not node then
return list
else
return node.next
end
end
function traverse(list) -- (for) expression
return getnext,list,nil
end
-- 。
list = nil
for line in io.lines() do
line = { val = line, next = list}
end
-- (for) 。
for node in traverse(list) do
print(node.val)
end
여기서 사용하는 기교는 체인 테이블의 두결점을 고정 상태(traverse가 되돌아오는 두 번째 값)로 하고 현재 노드를 제어 변수로 하는 것이다.교체기 함수 getnext () 를 처음 호출할 때, node는nil이기 때문에 함수는list를 첫 번째 결점으로 되돌려줍니다.후속 호출에서 node가 더 이상 nil이 아니기 때문에 교체기가 node로 되돌아옵니다.next, 체인 테이블 끝부분의 nil 결점을 되돌릴 때까지 범용 (for) 은 교체기의 반복이 끝났다는 것을 판단합니다.
마지막으로 설명해야 할 것은traverse() 함수와list 변수는 반복적으로 호출할 수 있으며 새로운closure 변수를 만들 필요가 없다는 것이다.이것은 주로 교체기 함수 (getnext) 가 무상태 교체기로 실현되기 때문이다.
4. 복잡한 상태의 교체기:
위에서 소개한 교체기 구현에서 교체기는 많은 상태를 저장해야 하지만 범형(for)은 고정된 상태와 제어 변수만 제공하여 상태의 저장에 사용한다.가장 간단한 방법은closure를 사용하는 것이다.물론 우리는 모든 정보를 하나의 테이블에 봉하여 고정된 상태의 대상으로 교체기에 전달한다.항정 상태 변수 자체는 항정이다. 즉, 교체 과정에서 다른 대상으로 바뀌지 않는다. 그러나 이 대상에 포함된 데이터의 변화 여부는 교체기의 실현에 달려 있다.현재로서는 테이블 형식의 고정 대상이 모든 교체기에 의존하는 정보를 포함하고 있기 때문에, 교체기는 일반 (for) 이 제공하는 두 번째 인자를 완전히 무시할 수 있다.다음은 다음과 같은 코드를 참조하여 다음과 같은 예를 보여 드리겠습니다.
local iterator
function allwords()
local state { line = io.read(), pos = 1 }
return iterator, state
end
--iterator
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
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.