Lua 언어 기초 집계 (10) - Lua 의 환경 개념

4190 단어
머리말
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

좋은 웹페이지 즐겨찾기