Lua 모듈 및 패키지
모듈은 패키지 라이브러리와 유사합니다. Lua 5.1부터 Lua에는 표준 모듈 관리 메커니즘이 추가되었습니다. 이를 통해 일부 공통 코드를 파일에 넣고 API 형식으로 다른 곳에서 호출할 수 있습니다. 인터페이스. 코드 재사용 및 코드 결합 감소에 도움이 됩니다.
Lua의 모듈은 변수, 함수 등 알려진 요소로 구성된 테이블이므로 모듈을 만드는 것은 매우 간단합니다. 테이블을 만든 다음 내보낼 상수와 함수를 그 안에 넣고 마지막으로 테이블을 돌려보내세요. 그게 다예요. 다음은 커스텀 모듈 module.lua를 생성한 예입니다. 파일 코드 형식은
-- 文件名为 module.lua -- 定义一个名为 module 的模块 module = {} -- 定义一个常量 module.constant = "这是一个常量" -- 定义一个函数 function module.func1() io.write("这是一个公有函数!\n") end local function func2() print("这是一个私有函数!") end function module.func3() func2() end return module
위에서 알 수 있듯이 모듈의 구조가 테이블 구조이므로 조작이 가능합니다. 호출 테이블의 요소를 조작하는 것과 마찬가지로 호출 모듈을 호출합니다.
위 func2는 프로그램 블록의 지역 변수로 선언되어 있는데, 이는 Private 함수를 의미하므로, 모듈의 이 Private 함수는 외부에서 접근할 수 없으며 Public 함수를 통해 호출해야 합니다.
require 함수
Lua에서는 모듈을 로드하는 데 require라는 함수를 제공합니다. 모듈을 로드하려면 간단히 호출하면 됩니다. 예:
require("<模块名>")
또는
require "<模块名>"
require를 실행하면 모듈 상수나 함수로 구성된 테이블이 반환되고, 해당 테이블을 포함하는 전역 변수도 정의됩니다.
-- test_module.lua 文件 -- module 模块为上文提到到 module.lua require("module") print(module.constant) module.func3()
위 코드의 실행 결과는 다음과 같습니다.
这是一个常量 这是一个私有函数!
또는 쉽게 호출할 수 있도록 로드된 모듈에 대한 별칭 변수를 정의합니다.
-- test_module2.lua 文件 -- module 模块为上文提到到 module.lua -- 别名变量 m local m = require("module") print(m.constant) m.func3()
위 코드의 실행 결과 is:
这是一个常量 这是一个私有函数!
로딩 메커니즘
사용자 정의 모듈의 경우 모듈 파일은 어떤 파일 디렉터리에 있는지는 중요하지 않습니다. require 함수에는 자체 파일 경로 로딩 전략이 있습니다. Lua 파일이나 C 라이브러리에서 로드하세요.
require Lua 파일을 검색하는 데 사용되는 경로는 전역 변수 package.path에 저장됩니다. Lua가 시작되면 이 환경 변수는 환경 변수 LUA_PATH의 값으로 초기화됩니다. 환경 변수를 찾을 수 없으면 컴파일 타임에 정의된 기본 경로가 초기화에 사용됩니다.
물론 LUA_PATH 환경 변수가 없으면 설정을 맞춤화하고 현재 사용자 루트 디렉터리에서 .profile 파일을 열 수도 있습니다(없으면 새로 생성하거나 .bashrc 파일을 엽니다) ), 예를 들어 "~/lua /"를 변경합니다. LUA_PATH 환경 변수에 경로를 추가합니다:
#LUA_PATH export LUA_PATH="~/lua/?.lua;;"
파일 경로는 ";"으로 구분되며 마지막 두 ";;"는 경로 뒤에는 원래 기본 경로가 옵니다.
다음으로 즉시 적용되도록 환경 변수 매개변수를 업데이트합니다.
source ~/.profile
package.path의 값이
/Users/dengjoe/lua/?.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua
라고 가정합니다. 그런 다음 require("module")이 호출되면 다음 파일 디렉터리를 열어 대상을 검색하려고 시도합니다.
/Users/dengjoe/lua/module.lua; ./module.lua /usr/local/share/lua/5.1/module.lua /usr/local/share/lua/5.1/module/init.lua /usr/local/lib/lua/5.1/module.lua /usr/local/lib/lua/5.1/module/init.lua
대상 파일이 발견되면 package.loadfile이 호출되어 모듈을 로드합니다. 그렇지 않으면 C 라이브러리로 이동합니다.
검색된 파일 경로는 전역 변수 package.cpath에서 구하며, 이 변수는 환경 변수 LUA_CPATH를 통해 초기화됩니다.
검색 전략은 위와 동일하지만 이제 so 또는 dll 유형 파일을 검색한다는 점만 다릅니다. 발견되면 require는 package.loadlib를 통해 이를 로드합니다.
C 패키지
Lua와 C는 C를 사용하여 Lua용 패키지를 작성하기 쉽습니다.
Lua로 작성된 패키지와 달리 C 패키지는 사용하기 전에 먼저 로드하고 연결해야 합니다. 대부분의 시스템에서 이를 구현하는 가장 쉬운 방법은 동적 링크 라이브러리 메커니즘을 이용하는 것입니다.
Lua는 loadlib라는 함수에서 모든 동적 연결 기능을 제공합니다. 이 함수는 라이브러리의 절대 경로와 초기화 함수라는 두 가지 매개변수를 사용합니다. 따라서 일반적인 호출 예는 다음과 같습니다.
local path = "/usr/local/lua/lib/libluasocket.so" local f = loadlib(path, "luaopen_socket")
loadlib 함수는 지정된 라이브러리를 로드하고 Lua에 연결하지만 라이브러리를 열지는 않습니다(즉, 초기화 함수를 호출하지 않습니다). , 초기화 함수를 Lua의 A 함수로 반환하므로 Lua에서 직접 호출할 수 있습니다.
동적 라이브러리를 로드하거나 초기화 함수를 찾을 때 오류가 발생하면 loadlib는 nil을 반환하고 오류 메시지를 표시합니다. 이전 코드 조각을 수정하여 오류를 감지한 다음 초기화 함수를 호출할 수 있습니다.
local path = "/usr/local/lua/lib/libluasocket.so" -- 或者 path = "C:\windows\luasocket.dll",这是 Window 平台下 local f = assert(loadlib(path, "luaopen_socket")) f() -- 真正打开库
일반적으로 바이너리 릴리스 라이브러리에는 이전 코드 조각과 유사한 스텁 파일이 포함되어 있다고 예상합니다. 바이너리를 설치할 수 있습니다. 라이브러리를 특정 디렉토리에 배치하고 스텁 파일에 해당하는 바이너리 라이브러리의 실제 경로를 수정하면 됩니다.
LUA_PATH에 스텁 파일이 있는 디렉터리를 추가합니다. 설정 후 require 함수를 사용하여 C 라이브러리를 로드할 수 있습니다.