Lua 언어 기초 집계 (10) - Lua 의 환경 개념
Lua 는 모든 전역 변 수 를 일반적인 table 에 저장 합 니 다. 이 table 을 '환경' 이 라 고 합 니 다.이러한 조직 구조의 장점 은 첫째, 전체 변 수 를 위해 새로운 데이터 구 조 를 만 들 필요 가 없 기 때문에 Lua 의 내부 실현 을 간소화 한 것 이다.또 다른 장점 은 다른 table 처럼 이 table 을 조작 할 수 있다 는 것 이다.이러한 조작 을 편리 하 게 하기 위해 Lua 는 환경 table 자 체 를 전역 변수 에 저장 합 니 다G 중.예 를 들 어, 우 리 는 현재 환경 에서 모든 전역 변수의 이름 을 아래 코드 로 인쇄 할 수 있다.
1
for
n in pairs(_G)
do
print(n) end
당신 의 컴퓨터 에서 이상 의 코드 를 실행 해서 결 과 를 보 세 요.
전역 변수 선언
Lua 에서 전역 변 수 는 성명 없 이 바로 사용 할 수 있 습 니 다. 그러나 이렇게 하면 프로 그래 밍 의 금기 사항 을 위반 하고 전역 변 수 를 마음대로 사용 하면 프로그램의 성능 을 초래 할 수 있 습 니 다. bug 가 발생 했 을 때 발견 하기 어렵 고 프로그램의 이름 도 오염 되 었 습 니 다.전역 변수 도 하나의 table 에 저 장 된 것 을 감안 하여 우 리 는 메타 표를 통 해 다른 코드 가 전역 변 수 를 방문 할 때의 행 위 를 바 꿀 수 있 습 니 다. 보 셨 습 니까?또 원 표 야?코드 는 다음 과 같 습 니 다:
1
2
3
4
5
6
7
8
9
10
setmetatable(_G, {
__newindex = function (_, k)
error(
"Attempt to write to undeclared variable "
.. k)
end,
__index = function (_, k)
error(
"Attempt to read undeclared variable "
.. k)
end
})
print(a) -- a
때때로 우 리 는 전역 변 수 를 정의 해 야 한다. 그러면 어떻게 해 야 합 니까?내 가 《 Lua 중의 원 표 와 원 법 》 이라는 글 에서 쓴 것 을 기억 하 십 니까?rawset 을 사용 하면 완성 할 수 있 습 니 다. 이것 은 원 표 와 달리 table 의 값 을 직접 설정 합 니 다.또한 하나의 변수 가 존재 하 는 지 테스트 하기 위해 서 는 nil 과 쉽게 비교 할 수 없습니다.만약 그것 이 nil 이 라면, 방문 에 오류 가 발생 할 것 입 니 다. 마찬가지 로, 우 리 는 rawget 을 사용 하여 원 을 돌아 갈 수 있 습 니 다.
전역 변수
'환경' 이라는 개념 은 전체 적 인 것 이기 때문에 그 에 대한 수정 은 프로그램의 모든 부분 에 영향 을 줄 것 이다.예 를 들 어 전체 변수의 접근 을 제어 하기 위해 메타 표를 설치 하면 전체 프로그램 은 이 규범 을 따라 야 합 니 다.그러나 어떤 라 이브 러 리 를 사용 할 때 먼저 설명 하지 않 고 전역 변 수 를 사 용 했 기 때문에 이 프로그램 은 실행 할 수 없습니다.
함수 setfenv 를 통 해 함수 의 환경 을 바 꿀 수 있 습 니 다.이 함수 의 매개 변 수 는 함수 와 새로운 환경 table 입 니 다.첫 번 째 매개 변 수 는 함수 자체 로 지정 할 수 있 을 뿐만 아니 라 현재 함수 호출 스 택 의 층수 도 표시 할 수 있 습 니 다.숫자 1 은 현재 함 수 를 나타 내 고 숫자 2 는 현재 함 수 를 호출 하 는 함 수 를 나타 내 며 이 를 유추 합 니 다.우선 코드 를 조금 만 주세요.
1
2
3
4
5
a = 1 --
-- table
setfenv(1, {})
print(a)
실행 코드 에서 이러한 오류 가 발생 합 니 다: attempt to call global 'print' (a nil value)
print 는G 에서 현재 환경 변 수 를 빈 table 로 초기 화하 기 때문에 print 를 찾 을 수 없어 서 오류 가 발생 했 습 니 다.이러한 잘못된 방생 을 방지 하기 위해 서 는 현재 환경 변 수 를 바 꾸 기 전에 현재 환경 변 수 를 저장 해 야 합 니 다.다음 코드 보기:
1
2
3
4
5
6
a = 1 --
-- table
setfenv(1, {g = _G})
g.print(a) -- nil
g.print(g.a) -- 1
이 때 g 를 방문 하면 원래 의 환경 을 얻 을 수 있 습 니 다. 이 환경 에는 필드 print 가 포함 되 어 있 습 니 다.우 리 는 이름 을 사용 할 수 있다G 는 g 를 대체 합 니 다. 다음 코드 와 같 습 니 다.
1
2
3
4
5
6
a = 1 --
-- table
setfenv(1, {_G = _G})
_G.print(a) -- nil
_G.print(_G.a) -- 1
우리 가 전에 정리 한 를 잊 지 마 세 요.index 메타 방법, 새로운 환경 변 수 를 설정 할 수 있 는index 는G. 이렇게 하면 새로운 환경 에서 대응 하 는 변 수 를 찾 지 못 할 때 갑 니 다G 에서 찾 으 면 새로운 환경 변수 가 전체적인 환경 변 수 를 계승 하 는 것 과 같 습 니 다G, 다음 코드 를 보십시오.
1
2
3
4
5
6
7
8
a = 1 --
local newEnv = {}
setmetatable(newEnv, {__index = _G})
-- table
setfenv(1, newEnv)
print(a)
Lua 에 서 는 함수 가 생 성 된 환경 을 계승 하기 때문에 하나의 프로그램 블록 이 자신의 환경 을 바 꾸 면 나중에 생 성 된 함수 가 이 새로운 환경 을 공유 합 니 다.이 메커니즘 은 이름 공간 을 만 드 는 데 매우 유용 하 다.이후 의 총결산 에 서 는 계속 설명 할 것 이다.
원본 주소:http://www.jellythink.com/archives/522
다음으로 전송:https://www.cnblogs.com/wodehao0808/p/3925383.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.