You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lua重复require时单例实现问题:多次引入会创建多实例吗?

Great question! Let's break this down step by step.

Will there be two some-library instances?

No, there won't be. Lua's require function has a built-in caching mechanism that prevents modules from being executed multiple times. Here's exactly what happens when you run lua file2:

  1. When file1 calls require('wrapper'), Lua executes the wrapper module's code: it loads some-library, creates an instance via some_library.new(...), and stores the resulting wrapper table in package.loaded['wrapper'].
  2. Later, when file2 calls require('wrapper'), Lua checks the package.loaded cache first. Since the wrapper module is already cached, it returns the existing wrapper table directly—it does not re-run the module code, so some_library.new(...) is only called once.

By default, you'll only ever have one instance of some-library in this setup.

How to explicitly implement a singleton (for extra safety or flexibility)

While Lua's require caching already ensures a module-level singleton, you can make this behavior more explicit or add flexibility (like lazy initialization) with these approaches:

1. Explicitly check the module cache

Modify your wrapper module to directly leverage Lua's cache system, making the singleton behavior obvious:

-- Check if we're already loaded in the package cache
local wrapper = package.loaded['wrapper']
if wrapper then
  return wrapper
end

wrapper = {}
local some_library = require('some-library')
wrapper._library = some_library.new(...)
-- Manually set the cache entry to lock in the singleton
package.loaded['wrapper'] = wrapper
return wrapper

This guards against edge cases where someone might modify package.loaded accidentally, ensuring no duplicate instances are created.

2. Hide the instance in a closure

Encapsulate the instance in a local closure so it's completely hidden from external code, only exposing the methods you want to make public:

local some_library = require('some-library')
-- The instance is a local variable, only accessible inside this module
local instance = some_library.new(...)

local wrapper = {}

-- Example: Proxy methods from the instance to the wrapper
function wrapper.perform_action(arg1, arg2)
  return instance:perform_action(arg1, arg2)
end

return wrapper

This makes the singleton truly immutable—external code can't modify or replace the instance, only interact with it via your defined methods.

3. Lazy initialization with a factory

If you need to initialize the instance with runtime parameters (not just when the module loads), use a factory function to manage the singleton:

local some_library = require('some-library')
local instance = nil

local wrapper = {}

-- Factory method to get or create the instance on demand
function wrapper.get_instance(...)
  if not instance then
    -- Initialize with arguments passed at runtime
    instance = some_library.new(...)
  end
  return instance
end

-- Optional: Automatically proxy wrapper method calls to the instance
setmetatable(wrapper, {
  __index = function(_, method_name)
    local inst = wrapper.get_instance()
    return inst[method_name]
  end
})

return wrapper

With this setup, you can delay instance creation until you have the necessary parameters, while still guaranteeing only one instance exists.


内容的提问来源于stack exchange,提问作者Kousha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:40:16