Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

学习 Lua #298

Open
nonocast opened this issue Jun 10, 2022 · 0 comments
Open

学习 Lua #298

nonocast opened this issue Jun 10, 2022 · 0 comments

Comments

@nonocast
Copy link
Owner

nonocast commented Jun 10, 2022

hello world

通过brew或者make install都可以很容易的安装lua。

shell 运行:

 ~ lua
Lua 5.4.4  Copyright (C) 1994-2022 Lua.org, PUC-Rio
> print "hello world"
hello world

script 运行:

~ echo 'print "hello world"' > hello.lua
~ lua hello.lua 
hello world

语法

注释

-- single line comment

--[[
multiline comments
multiline comments
multiline comments
--]]

print("hello world")

变量

x = 1
x = 3.0
x = 0x1f
y = true
z = "nonocast"
local u = 1
  • 不需要let, var, 拿来就用
  • 数字都是64bit double,不要在意
  • 字符串单引号双引号都可以
  • lua中的NULL和swift一样用nil
  • true, false表示boolean
  • 不加local都全部是全局变量

控制语句

while

i = 0
while i < 5 do
  print(i)
  i = i + 1
end
  • 没有i++i += 1的操作

if

i = 0

if(i < 5) then
  print "i < 5"
else
  print "i >= 5"
end
  • 不等于是~=

for

for i = 1, 10 do
  print(i)
end

IO相关

io.write("enter your name: ")
name = io.read()
print("hello, "..name)
  • ..表示字符串concat
  • io.write/io.read对应stdin, stdout

函数

function

function fib(n)
  if n < 2 then return 1 end
  return fib(n - 2) + fib(n - 1)
end

for i = 1, 15 do
  print(fib(i))
end

lambda

function fib(n)
  if n < 2 then return 1 end
  return fib(n - 2) + fib(n - 1)
end

for i = 1, 15 do
  print(fib(i))
end

return

function getUserById(id)
  print(id)
  return "nonocast", 37, "[email protected]"
end

name, age, email = getUserById()
print(name, age, email)

Table

nonocast = { name="nonocast", age=21, email="[email protected]" }
print(nonocast.name)

this

nonocast = { 
  name="nonocast", 
  age=21, 
  email="[email protected]",
  hi=function(self) print("hi, "..self.name) end
}

nonocast:hi()

模块

和nodejs很类似

foo.lua

print("foo")

hello.lua

require("foo")
print("hello")

Lua & C

Lua和C等同于Swift和C,也等同于Javascript和C (quickjs)

foo.lua

echo()

app.c

// clang -Wall -llua -o app app.c
#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

int echo(lua_State *L) {
  printf("hello, lua\n");
  return 0;
}

int main(void) {
  lua_State *L = luaL_newstate();
  lua_register(L, "echo", echo);
  luaL_openlibs(L);
  luaL_dofile(L, "foo.lua");
  lua_close(L);

  return 0;
}

如果scirpt是用户配置数据库中,则可以直接采用更底层的luaL_dostring

const char *script = "echo()";
luaL_dostring(L, script);

这样就非常简单的实现了从Lua直接call到C的方法,通过lua script扩展C的核心能力。由于lua本身就是依托C,所以互相调用会非常方便,而swift,js只能说是不得不兼容C,从易用性的角度来说lua和c是绝配。

LuaJIT

Difference Lua Luajit – Shahzheeb Khan – Open Source Enthusiast

简单来说,luajit是一个更高效率的lua实现。OpenResty和Redis都采用了LuaJIT。

Lua原生的实现17000行C,到了LuaJIT就将近50000行C,可见通过复杂度换性能。几个特点:

  • luajit可以将lua script编译成luajit bytecode,类似java的class
  • 支持FFI, 直接在lua中调用C
  • 支持交叉编译,即在x86_84 windows上可以直接编译x86_64 macos, x86_64 linux又或者arm64

OpenResty

传送: openresty 简介 - 戴磊笔记

OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

OpenResty 以 Nginx 为核心,集成打包了众多的侧重于高性能Web开发的外围组件,它既是一个 web 服务器,更是一个成熟完善的开发环境。OpenResty 成功地把 Lua 语言嵌入到了 Nginx,用 Lua 作为 "胶水语言" 粘合 Nginx 的各个模块和底层接口,以脚本的方式直接实现复杂的HTTP/ TCP/UDP业务逻辑,降低了 Web Server 特别是高性能 Web server的开发门槛。

OpenResty 基于Lua5.1/LuaJit,充分利用了Lua内建的协程特性,可以无阻塞处理并发连接,而且功能代码不需要编译,可以就地修改脚本并运行,简化了开发流程,加快了开发和调试的速度,同时也缩短了开发周期,在如今这个快节奏的时代里弥足珍贵 。很多国内外大型网站都在使用 OpenRest开发后端应用,而且越来越多,知名的有 Adobe、 CloudFlare、 Dropbox、 GitHub等,充分地证明了 OpenResty 的优秀。

所以,OpenResty就是nginx+lua+一系列基于nginx的扩展。传送: 序 · OpenResty最佳实践

另,Kong基于OpenResty,在Github上32k stars,cloc看了一下竟然有17万行lua, 从侧面证明lua也不完全是C附属品,足够强大。

参考阅读

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant