1-8、Lua编译-运行-错误信息

2023-11-02

1-8、Lua编译-运行-错误信息



虽然我们把Lua当作解释型语言,但是Lua会首先把代码预编译成中间码然后再执行(很多解释型语言都是这么做的)。在解释型语言中存在编译阶段听起来不合适,然而,解释型语言的特征不在于他们是否被编译,而是编译器是语言运行时的一部分,所以,执行编译产生的中间码速度会更快。我们可以说函数dofile的存在就是说明可以将Lua作为一种解释型语言被调用。
前面我们介绍过dofile,把它当作Lua运行代码的chunk的一种原始的操作。dofile实际上是一个辅助的函数。真正完成功能的函数是loadfile;与dofile不同的是loadfile编译代码成中间码并且返回编译后的chunk作为一个函数,而不执行代码;另外loadfile不会抛出错误信息而是返回错误码。我们可以这样定义dofile:

function dofile (filename)
	local f = assert(loadfile(filename))
	return f()
end

如果loadfile失败assert会抛出错误。
完成简单的功能dofile比较方便,他读入文件编译并且执行。然而loadfile更加灵活。在发生错误的情况下,loadfile返回nil和错误信息,这样我们就可以自定义错误处理。另外,如果我们运行一个文件多次的话,loadfile只需要编译一次,但可多次运行。dofile却每次都要编译。
loadstring与loadfile相似,只不过它不是从文件里读入chunk,而是从一个串中读入。例如:

f = loadstring("i = i + 1")
f将是一个函数,调用时执行i=i+1。
i = 0
f(); print(i)		--> 1
f(); print(i)		--> 2

loadstring函数功能强大,但使用时需多加小心。确认没有其它简单的解决问题的方法再使用。
Lua把每一个chunk都作为一个匿名函数处理。例如:chunk “a = 1”,loadstring返回与其等价的function () a = 1 end
与其他函数一样,chunks可以定义局部变量也可以返回值:

f = loadstring("local a = 10; return a + 20")
print(f())			--> 30

loadfile和loadstring都不会抛出错误,如果发生错误他们将返回nil加上错误信息:

print(loadstring("i i"))
		--> nil	[string "i i"]:1: '=' expected near 'i'

另外,loadfile和loadstring都不会有边界效应产生,他们仅仅编译chunk成为自己内部实现的一个匿名函数。通常对他们的误解是他们定义了函数。Lua中的函数定义是发生在运行时的赋值而不是发生在编译时。假如我们有一个文件foo.lua:

-- file `foo.lua'
function foo (x)
	print(x)
end

当我们执行命令f = loadfile(“foo.lua”)后,foo被编译了但还没有被定义,如果要定义他必须运行chunk:

f()				-- defines `foo'
foo("ok")		--> ok

如果你想快捷的调用dostring(比如加载并运行),可以这样

loadstring(s)()

调用loadstring返回的结果,然而如果加载的内容存在语法错误的话,loadstring返回nil和错误信息(attempt to call a nil value);为了返回更清楚的错误信息可以使用assert:

assert(loadstring(s))()

通常使用loadstring加载一个字串没什么意义,例如:

f = loadstring("i = i + 1")

大概与f = function () i = i + 1 end等价,但是第二段代码速度更快因为它只需要编译一次,第一段代码每次调用loadstring都会重新编译,还有一个重要区别:loadstring编译的时候不关心词法范围:

local i = 0
f = loadstring("i = i + 1")
g = function () i = i + 1 end

这个例子中,和想象的一样g使用局部变量i,然而f使用全局变量i;loadstring总是在全局环境中编译他的串。
loadstring通常用于运行程序外部的代码,比如运行用户自定义的代码。注意:loadstring期望一个chunk,即语句。如果想要加载表达式,需要在表达式前加return,那样将返回表达式的值。看例子:

print "enter your expression:"
local l = io.read()
local func = assert(loadstring("return " .. l))
print("the value of your expression is " .. func())

loadstring返回的函数和普通函数一样,可以多次被调用:

print "enter function to be plotted (with variable 'x'):"
local l = io.read()
local f = assert(loadstring("return " .. l))
for i=1,20 do
	x = i   -- global 'x' (to be visible from the chunk)
	print(string.rep("*", f()))
end

1、require函数

Lua提供高级的require函数来加载运行库。粗略的说require和dofile完成同样的功能但有两点不同:

  • 1.require会搜索目录加载文件
  • 2.require会判断是否文件已经加载避免重复加载同一文件。由于上述特征,require在Lua中是加载库的更好的函数。
    require使用的路径和普通我们看到的路径还有些区别,我们一般见到的路径都是一个目录列表。require的路径是一个模式列表,每一个模式指明一种由虚文件名(require的参数)转成实文件名的方法。更明确地说,每一个模式是一个包含可选的问号的文件名。匹配的时候Lua会首先将问号用虚文件名替换,然后看是否有这样的文件存在。如果不存在继续用同样的方法用第二个模式匹配。例如,路径如下:
?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua

调用require "lili"时会试着打开这些文件:

lili
lili.lua
c:\windows\lili
/usr/local/lua/lili/lili.lua

require关注的问题只有分号(模式之间的分隔符)和问号,其他的信息(目录分隔符,文件扩展名)在路径中定义。
为了确定路径,Lua首先检查全局变量LUA_PATH是否为一个字符串,如果是则认为这个串就是路径;否则require检查环境变量LUA_PATH的值,如果两个都失败require使用固定的路径(典型的"?;?.lua")require的另一个功能是避免重复加载同一个文件两次。Lua保留一张所有已经加载的文件的列表(使用table保存)。如果一个加载的文件在表中存在require简单的返回;表中保留加载的文件的虚名,而不是实文件名。所以如果你使用不同的虚文件名require同一个文件两次,将会加载两次该文件。比如require “foo"和require “foo.lua”,路径为”?;?.lua"将会加载foo.lua两次。我们也可以通过全局变量_LOADED访问文件名列表,这样我们就可以判断文件是否被加载过;同样我们也可以使用一点小技巧让require加载一个文件两次。比如,require "foo"之后_LOADED[“foo”]将不为nil,我们可以将其赋值为nil,require "foo.lua"将会再次加载该文件。

一个路径中的模式也可以不包含问号而只是一个固定的路径,比如:

?;?.lua;/usr/local/default.lua

这种情况下,require没有匹配的时候就会使用这个固定的文件(当然这个固定的路径必须放在模式列表的最后才有意义)。在require运行一个chunk以前,它定义了一个全局变量_REQUIREDNAME用来保存被required的虚文件的文件名。我们可以通过使用这个技巧扩展require的功能。举个极端的例子,我们可以把路径设为"/usr/local/lua/newrequire.lua",这样以后每次调用require都会运行newrequire.lua,这种情况下可以通过使用_REQUIREDNAME的值去实际加载required的文件。

2、C Packages

Lua和C是很容易结合的,使用C为Lua写包。与Lua中写包不同,C包在使用以前必须首先加载并连接,在大多数系统中最容易的实现方式是通过动态连接库机制,然而动态连接库不是ANSI C的一部分,也就是说在标准C中实现动态连接是很困难的。

通常Lua不包含任何不能用标准C实现的机制,动态连接库是一个特例。我们可以将动态连接库机制视为其他机制之母:一旦我们拥有了动态连接机制,我们就可以动态的加载Lua中不存在的机制。所以,在这种特殊情况下,Lua打破了他平台兼容的原则而通过条件编译的方式为一些平台实现了动态连接机制。标准的Lua为windows、Linux、FreeBSD、Solaris和其他一些Unix平台实现了这种机制,扩展其它平台支持这种机制也是不难的。在Lua提示符下运行print(loadlib())看返回的结果,如果显示bad arguments则说明你的发布版支持动态连接机制,否则说明动态连接机制不支持或者没有安装。

Lua在一个叫loadlib的函数内提供了所有的动态连接的功能。这个函数有两个参数:库的绝对路径和初始化函数。所以典型的调用的例子如下:

local path = "/usr/local/lua/lib/libluasocket.so"
local f = loadlib(path, "luaopen_socket")

loadlib函数加载指定的库并且连接到Lua,然而它并不打开库(也就是说没有调用初始化函数),反之他返回初始化函数作为Lua的一个函数,这样我们就可以直接在Lua中调用他。如果加载动态库或者查找初始化函数时出错,loadlib将返回nil和错误信息。我们可以修改前面一段代码,使其检测错误然后调用初始化函数:

local path = "/usr/local/lua/lib/libluasocket.so"
-- or path = "C:\\windows\\luasocket.dll"
local f = assert(loadlib(path, "luaopen_socket"))
f()  -- actually open the library

一般情况下我们期望二进制的发布库包含一个与前面代码段相似的stub文件,安装二进制库的时候可以随便放在某个目录,只需要修改stub文件对应二进制库的实际路径即可。将stub文件所在的目录加入到LUA_PATH,这样设定后就可以使用require函数加载C库了。

3、错误

Errare humanum est(拉丁谚语:犯错是人的本性)。所以我们要尽可能的防止错误的发生,Lua经常作为扩展语言嵌入在别的应用中,所以不能当错误发生时简单的崩溃或者退出。相反,当错误发生时Lua结束当前的chunk并返回到应用中。
当Lua遇到不期望的情况时就会抛出错误,比如:两个非数字进行相加;调用一个非函数的变量;访问表中不存在的值等(可以通过metatables修改这种行为,后面介绍)。你也可以通过调用error函数显式地抛出错误,error的参数是要抛出的错误信息。

print "enter a number:"
n = io.read("*number")
if not n then error("invalid input") end

Lua提供了专门的内置函数assert来完成上面类似的功能:

print "enter a number:"
n = assert(io.read("*number"), "invalid input")

assert首先检查第一个参数,若没问题,assert不做任何事情;否则,assert以第二个参数作为错误信息抛出。第二个参数是可选的。注意,assert会首先处理两个参数,然后才调用函数,所以下面代码,无论n是否为数字,字符串连接操作总会执行:

n = io.read()
assert(tonumber(n), "invalid input: " .. n .. " is not a number")

当函数遇到异常有两个基本的动作:返回错误代码或者抛出错误。选择哪一种方式,没有固定的规则,不过基本的原则是:对于程序逻辑上能够避免的异常,以抛出错误的方式处理之,否则返回错误代码。
例如sin函数,假定我们让sin碰到错误时返回错误代码,则使用sin的代码可能变为:

local res = math.sin(x)
if not res then		-- error
	...
当然,我们也可以在调用sin前检查x是否为数字:
if not tonumber(x) then		-- error: x is not a number
...

而事实上,我们既不是检查参数也不是检查返回结果,因为参数错误可能意味着我们的程序某个地方存在问题,这种情况下,处理异常最简单最实际的方式是抛出错误并且终止代码的运行。
再来看一个例子。io.open函数用于打开文件,如果文件不存在,结果会如何?很多系统中,我们通过“试着去打开文件”来判断文件是否存在。所以如果io.open不能打开文件(由于文件不存在或者没有权限),函数返回nil和错误信息。依据这种方式,我们可以通过与用户交互(比如:是否要打开另一个文件)合理地处理问题:

local file, msg
repeat
	print "enter a file name:"
	local name = io.read()
	if not name then return end		-- no input
	file, msg = io.open(name, "r")
	if not file then print(msg) end
until file

如果你想偷懒不想处理这些情况,又想代码安全的运行,可以使用assert:

file = assert(io.open(name, "r"))

Lua中有一个习惯:如果io.open失败,assert将抛出错误。

file = assert(io.open("no-file", "r"))
		--> stdin:1: no-file: No such file or directory

注意:io.open返回的第二个结果(错误信息)会作为assert的第二个参数。

4、异常和错误处理

很多应用中,不需要在Lua进行错误处理,一般有应用来完成。通常应用要求Lua运行一段chunk,如果发生异常,应用根据Lua返回的错误代码进行处理。在控制台模式下的Lua解释器如果遇到异常,打印出错误然后继续显示提示符等待下一个命令。
如果在Lua中需要处理错误,需要使用pcall函数封装你的代码。
假定你想运行一段Lua代码,这段代码运行过程中可以捕捉所有的异常和错误。

  • 第一步:将这段代码封装在一个函数内
function foo ()
	...
	if unexpected_condition then error() end
	...
	print(a[i])	-- potential error: `a' may not be a table
	...
end
  • 第二步:使用pcall调用这个函数
if pcall(foo) then
	-- no errors while running `foo'
	...
else
	-- `foo' raised an error: take appropriate actions
	...
end

当然也可以用匿名函数的方式调用pcall:

if pcall(function () ... end) then ...
else ...

pcall在保护模式(protected mode)下执行函数内容,同时捕获所有的异常和错误。若一切正常,pcall返回true以及“被执行函数”的返回值;否则返回nil和错误信息。
错误信息不一定仅为字符串(下面的例子是一个table),传递给error的任何信息都会被pcall返回:

local status, err = pcall(function () error({code=121}) end)
print(err.code)  -->  121

这种机制提供了强大的能力,足以应付Lua中的各种异常和错误情况。我们通过error抛出异常,然后通过pcall捕获之。

5、错误信息和回跟踪(Tracebacks)

虽然你可以使用任何类型的值作为错误信息,通常情况下,我们使用字符串来描述遇到的错误。如果遇到内部错误(比如对一个非table的值使用索引下标访问)Lua将自己产生错误信息,否则Lua使用传递给error函数的参数作为错误信息。不管在什么情况下,Lua都尽可能清楚的描述问题发生的缘由。

local status, err = pcall(function () a = 'a'+1 end)
print(err)
--> stdin:1: attempt to perform arithmetic on a string value

local status, err = pcall(function () error("my error") end)
print(err)
--> stdin:1: my error

例子中错误信息给出了文件名(stdin)与行号。
函数error还可以有第二个参数,表示错误发生的层级。比如,你写了一个函数用来检查“error是否被正确调用”:

function foo (str)
	if type(str) ~= "string" then
		error("string expected")
	end
	...
end

可有人这样调用此函数:

foo({x=1})

Lua会指出发生错误的是foo而不是error,实际上,错误是调用error时产生的。为了纠正这个问题,修改前面的代码让error报告错误发生在第二级(你自己的函数是第一级)如下:

function foo (str)
	if type(str) ~= "string" then
		error("string expected", 2)
	end
	...
end

当错误发生的时候,我们常常希望了解详细的信息,而不仅是错误发生的位置。若能了解到“错误发生时的栈信息”就好了,但pcall返回错误信息时,已经释放了保存错误发生情况的栈信息。因此,若想得到tracebacks,我们必须在pcall返回以前获取。Lua提供了xpcall来实现这个功能,xpcall接受两个参数:调用函数、错误处理函数。当错误发生时,Lua会在栈释放以前调用错误处理函数,因此可以使用debug库收集错误相关信息。有两个常用的debug处理函数:debug.debug和debug.traceback,前者给出Lua的提示符,你可以自己动手察看错误发生时的情况;后者通过traceback创建更多的错误信息,也是控制台解释器用来构建错误信息的函数。你可以在任何时候调用debug.traceback获取当前运行的traceback信息:

print(debug.traceback())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

1-8、Lua编译-运行-错误信息 的相关文章

  • Lua解释器相当于Matlab“whos”命令吗?

    Octave Matlab IPython whos 命令的 Lua 等价物是什么 我正在尝试以交互方式学习 Lua 并想看看当前定义了哪些变量 Lua 中的所有全局变量都驻留在可用作全局变量的表中 G http www lua org m
  • lua __pairs 的实际实现是什么?

    有谁知道 lua 5 2 的实际实现吗 元方法 pairs 换句话说 我如何实施 pairs作为元表中的元方法 因此它的工作原理与pairs 我需要覆盖 pairs并想跳过我在表中添加的一些虚拟变量 下面将使用元表元来显式提供pairs默认
  • 逐行编写 Lua 脚本

    我使用以下命令将 Lua 脚本添加到我的 C 应用程序中动态Lua http dynamiclua codeplex com 图书馆 它运作得很好 我想实现您获取正在执行的当前行 就像在 Visual Studio 中一样 并突出显示它 目
  • 设置私有 luarocks 存储库

    对于我的设置 我需要一个 luarocks rock 的私有存储库 我可以将它们安装在我的开发环境中 而无需连接到互联网 为 luarocks 设置远程存储库的步骤是什么 我可以使用 sftp 服务器吗 有人有过这样的经历吗 在深入研究这个
  • 无法在cmake中使用find_package找到Lua标头

    我正在尝试使用 CMake 为我使用 Lua 的项目构建生成 make 文件 当我运行 make 时出现此错误 path to my project luaudio luaudio c 1 17 fatal error lua h No s
  • 如何加载目录中的所有文件?

    正如标题所说 如何加载目录中的每个文件 我对c 和lua都感兴趣 编辑 对于 Windows 我很高兴能得到一些真正的工作代码 尤其是 lua 我可以用 boost filesystem for c 来做 对于 Lua 你需要模块Lua文件
  • 为什么这个 Lua 优化 hack 会提高性能?

    我正在寻找一个描述提高 Lua 性能的各种技术的文档 http www lua org gems sample pdf脚本代码 我很震惊竟然需要这样的技巧 虽然我引用的是 Lua 但我在 Javascript 中也见过类似的 hack 为什
  • 在 lua 中使用相等运算符比较数字有多安全?

    在我的引擎中 我有一个用于脚本编写的 Lua VM 在脚本中 我写了这样的内容 stage stage 1 if stage 5 then end and objnum tonumber 5 if stage objnum 根据 Lua 来
  • Lua - 尝试调用全局(零值)

    执行此代码时 出现错误 尝试调用全局 forId 零值 function execute args local itemid 526 local bone forId itemid this is where the error occur
  • 如何访问废弃的函数参数?

    在 Lua 中 调用带有多余参数的函数将简单地丢弃这些参数 有没有可能与debug库来访问这些被丢弃的参数 我不是在寻找可变参数函数 function test local info debug getinfo 1 u print info
  • 如何在多个Lua State(多线程)之间传递数据?

    我在中启动Redis连接池redis lua 通过从 C 调用 我得到了redis lua state 此 Lua 状态全局启动一次 仅在其他线程中启动get从中 当有一个 HTTP 请求 工作线程 时 我需要从redis lua stat
  • 十六进制常数 = 格式错误的数字?

    我有一个 Lua 脚本 我试图在其中使用十六进制数字 0x 如果我使用官方 Windows 二进制文件在控制台中运行此脚本 它可以正常工作 但是如果我在我的应用程序中运行它 简单的 dofile 我得到 malformed number n
  • 什么更快?循环或多个 if 条件

    我想知道什么更快 是只用一条指令 即 1 1 执行 9 次 for 循环还是执行 9 个 if 条件时 我认为 if 更快 因为您不需要检查循环中的指令 它应该几乎相同 因为for循环本质上是检查if条件为真并运行一段代码 非常类似于if声
  • Lua-迭代嵌套表

    我已经学习 Lua 几个星期了 这一次又一次成为我的症结所在 我尝试阅读有关该主题的帖子和书籍 我使用 Lua 查询软件监控系统 Nimsoft 我的数据以表格形式返回给我 我不会发布整个输出 但这里有一个我认为可以描述结构的片段 表参考是
  • 什么时候适合使用Lua这样的嵌入式脚本语言

    我玩 魔兽世界 大约有两年了 我对用来编写插件的 Lua 很好奇 由于到目前为止我读到的有关 Lua 的内容都是 快 轻 和 这太棒了 所以我想知道如何以及何时使用它 您需要在系统中嵌入像 Lua 这样的脚本语言的典型情况是什么 当您需要最
  • 在lua中组合两个函数

    我刚开始学习lua 所以我的要求可能是不可能的 现在 我有一个接受函数的方法 function adjust focused window fn local win window focusedwindow local winframe w
  • 比较 Lua 中的日期

    我有一个带有日期表的变量 如下所示 table day number 15 year number 2015 month number 2 如何获取当前日期与上述日期之间的天数 非常感谢 您可以使用os time 将表转换为秒并获取当前时间
  • 如何在我的 Lua 脚本中添加“睡眠”或“等待”?

    我正在尝试通过更改一天中的时间来为游戏制作一个简单的脚本 但我想快速完成 这就是我要说的 function disco hour minute setTime 1 0 SLEEP setTime 2 0 SLEEP setTime 3 0
  • Openresty 中的并发模型是什么?

    我很难理解 openresty 或 nginx 的并发模型 我读了Lua变量作用域 http wiki nginx org HttpLuaModule Lua Variable Scope 它解释了变量的生命周期 但它没有说明对它们的并发访
  • Lua 访问表的键和值

    我想在关卡编辑器中读取 Lua 文件 这样我就可以以可视化格式显示其数据供用户编辑 如果我有一个像这样的 Lua 表 properties Speed 10 TurnSpeed 5 Speed显然是关键并且10价值 我知道如果我知道像这样的

随机推荐

  • conda create -n python 3.6_conda create 怎么创建纯净的 Python3.6 环境?

    刚接触 conda 安装了 Anaconda3 想用 conda create 命令创建一个只含标准模块和几个必需第三方模块 如 pip wheel 的 Python3 6 环境 使用命令 conda create n test pytho
  • 核心思想_[转载]用最浅显的语言解释佛法的核心思想:缘起性空(即般若)

    本文是在 用最浅显的语言解释佛法的核心思想 缘起性空http tieba baidu com p 3074939669 一文基础上 重新修改而成 有兴趣的可以对比 参考原文 从缘起性空 到三界唯心 万法唯识 到涅槃寂静 直到大乘如来藏思想
  • 13天带你了解C++ ---DAY10 C++之vector

    目录 1 string容器 2 构造函数和析构函数的相关操作 3 迭代器 4 容量相关 5 元素访问相关 6 元素遍历相关 7 元素操作相关 8 vector模拟实现 1 string容器 vector容器是C 标准模板库提供的管理任意元素
  • mysql导入csv中文数据乱码问题分析与解决

    摘要 解决csv文件向mysql导入含有中文数据 导入后中文出现乱码问题 结论 在导入含中文字符时注意两个问题 第一 告诉Mysql文件的编码是什么 第二 数据库表中的列编码要设置成支持中文的字符集 导入源数据 SQL代码 LOAD DAT
  • mysql语句

    各种sql语句 一 引言 二 sql基础语句 1 sql新增语句 2 sql查询语句 3 sql修改语句 4 sql删除语句 5 sql其他语句 5 1 sql倒序 正序查询 5 2 sql表行数查询 三 sql较有深度语句 1 sql主从
  • Linux ip地址报错(Temporary failure in name resolution)活检地址检查

    1 项目健康检查报错 报错信息 java net UnknownHostException Temporary failure in name resolution 解决办法 hostname 查看主机名 hostname i 查看本机对应
  • PHPstorm必备插件推荐

    1 env files support 对 env 文件的支持 2 ignore 对 ignore 文件的支持 3 Ideolog 对 log 文件的支持 4 Chinese Simplified Language Pack 中文语言包 官
  • 抖音视频号情感类短视频爆火,背后有什么特点?有什么值得借鉴

    有一些人渐渐不联系了 不是因为淡了远了 而是没有合适的身份陪伴 没有合适的理由联络 没有合适的机会见面 只能放在心里偶尔回忆 经常想念 明明只是一张动图 但却可以让人自动脑补了早期抖音情感博主在线念白的腔调 没错 这些曾经在抖音快手风靡一时
  • 阿里犸良导出的json文件怎么使用

    犸良是什么 犸良作为一站式动效制作平台 通过海量的动效素材以及可视化编辑能力 帮助零基础的用户轻松完成动效制作 支持全平台iOS Android H5 小程序 无论是营销展位 活动页面 空状态还是产品icon 让动效更简单 官网地址 htt
  • pear-admin-flask开源后台模板(适合于毕设)

    Pear Admin Flask 开 箱 即 用 的 Flask 快 速 开 发 平 台 预 览 官 网 群聊 社区 项目简介 Pear Admin Flask 基于 Flask 的后台管理系统 拥抱应用广泛的python语言 通过使用本系
  • C# 如何向String[]字符数组插入数据

    C 如何向String 字符数组插入数据 思路 了解 由于数组是非动态的 不能进行动态的添加 思路 首先将string 字符数组转换成list 第二给list添加数据 最后把list转换成string 数组 String arrs new
  • 怎么上传文件到spark服务器上,从SFTP服务器加载文件到spark RDD

    您可以以下方式使用spark sftp库在你的程序 火花2 x的 Maven的依赖 com springml spark sftp 2 11 1 1 0 SBT依赖 libraryDependencies com springml spar
  • Effective(Modern)C++笔记01

    Effectice C 01 条款01 视C 为一个语言联邦 C 区块 blocks 语句 statements 预处理 preprocessor 内置数据类型 built in data types 数组 arrays 指针 pointe
  • 安装zookeeper集群,开启正常,但status显示./zkServer.sh :line 170:exec :java:not found

    笔者安装过很多次zookeeper集群 但是在一个新的生产环境上遇到了zookeeper的启动异常问题 可以先使用 zkServer sh start foreground 来查看详细报错信息 若发现是 zkServer sh line 1
  • Segment Anything开源项目学习记录

    一 什么是Segment Anything开源项目 Introduction We introduce the Segment Anything SA project a new task model and dataset for ima
  • 滚动页面到指定位置动画展示-Vue自定义命令-IntersectionObserver-animate.css

    最近在做公司官网 web H5 页面滚动显示出来给个小动画 之前了解的浏览器标准解决方案 不向下兼容 是 IntersectionObserver 是一个全局的侦听器 但是每个页面去做一个实例去侦听当前对象也觉得太冗余了吧 并且在vue里面
  • 逻辑分析仪的使用

    目录 逻辑分析仪与示波器的区别 逻辑分析仪 DSView 软件安装与简介 波形采集 波形分析 分析I2S协议 逻辑分析仪与示波器的区别 参考 https www bilibili com video BV1mz4y127jn spm id
  • 详解环境变量

    目录 前言 一 什么是环境变量 二 查看环境变量的方法 三 查看环境变量的内容 四 普通变量VS环境变量 五 导出环境变量 六 常见的环境变量 七 set命令 查看普通变量或环境变量 八 C C 语言中main函数中的参数 1 main函数
  • C#操作Excel总结

    0 导入命名空间 1 2 3 4 using Microsoft Office Core using Microsoft Office Interop Excel
  • 1-8、Lua编译-运行-错误信息

    1 8 Lua编译 运行 错误信息 文章目录 1 8 Lua编译 运行 错误信息 1 require函数 2 C Packages 3 错误 4 异常和错误处理 5 错误信息和回跟踪 Tracebacks 虽然我们把Lua当作解释型语言 但