Programming in Lua 4th Edition

5.3 加入 64-bit integer, 以前只有 double-precision floating;
small lua: 32-bit integers and single-precision floats;
Both integer and float values have type "number".

  • math.type

floating-point hexadecimal constants

0xa.bp2 -- (10 + 11/16) * 4, Lua 5.2 引入

string.format("%a", 0.1)

division of two integers does not need to be an integer

5.3 引入 //

modulo always having the same sign as the second argument.

math.pi - math.pi % 0.01

~=

math.min(1, 2)
math.huge -- inf
math.randomseed(os.time())
math.random() -- [0, 1), die [1, n], [l, u]
math.rad
math.deg
floor, ceil, and modf -- modf rounds towards zero
math.modf(-3.3) -- -3, -0.3

-math.mininteger == math.mininteger
math.maxinteger + 2.0 == math.maxinteger + 1.0 -- true

lose precision

2^53 | 0 -- integer
-- number has an exact representation as an integer

math.tointeger(5.01) -- nil, not an integral value
math.tointeger(2^64) -- nil, out of range

^
unary operators (- # ~ not)

  • / // %

.. (concatentation)
<< >> (bitwise shifts)
&
(bitwise AND)
~ (bitwise exclusive OR)
| (bitwise OR)
< > <= >= ~= ==
and
or

All binary operators are left associative,
except for exponentiation and concatenation,
which are right associative.

Lua 5.2 can represent exact integers only up to 2^53 ,
while in Lua 5.3 the limit is 2^63

(2^62|0) + (2^62|0) -1 == math.maxinteger

math.maxinteger * math.maxinteger
math.mininteger * math.mininteger

Strings in Lua are immutable values.

print(#"你h") -- 4, in bytes

'ok' .. 2 -- If any operand is a number, Lua converts this number to a string:

'
"
\ddd \xhh \u{hhh} -- \ddd 是 10 进制

long string, ignore the first character
[[....]]
[===[.......]===]

data = "\x00\x01\z
\x08"

automatic conversions between numbers and strings at run time

"10" + 1 -- 11.0 不完美的 lua
强大的 tonumber 和 math.tointeger(" 10")
tonumber 可以使用进制
tonumber("-ZZ", 36)
tonumber("9", 8) -- nil
tostring, 但是还是建议用 string.format

string.len -- #s
string.rep
string.reverse
string.sub(s, i, j) -- [i, j]
string.char(...)
string.byte(''[, start[, end]]) -- limit stack size

s:sub(i, j)
string.find("hello world", "war") -- nil

string.gsub 返回 2 个值

reverse,upper, lower, byte, and char
do not work for UTF-8 strings,
as all of them assume that one character
is equivalent to one byte.

utf8.len("ab\x93") -- nil 3
utf8.char(0x4f60) -- 你
utf8.codepoint(s, utf8.offset(s, 5))
utf8.codes

nil 不能作为 table 的 key

like global variables,
table fields evaluate to nil when not initialized.

tbl[2] == tbl[2.0]
2 compares equal to 2.0
tbl[1/3] 也是合法的
a = {x = 10, y = 20}
we cannot initialize fields with negative
indices, nor with string indices that are not proper identifiers.

tbl 可以用, 或 ; 分隔

without holes a sequence

The length operator is unreliable for lists with holes (nils)

a table with no numeric keys is a sequence with length zero.

If you really need to handle lists
with holes, you should store the length explicitly somewhere.

io.lines()
table.insert
table.remove

-- insert begin
table.move(a, 1, #a, 2)
a[1] = newElement

-- remove first
table.move(a, 2, #a, 1) -- copy
a[#a] = nil

table.move 从一个到另外一个tbl

function

if the function has
one single argument and that argument is either a literal string or a table constructor, then the parentheses
are optional:

function with a number of arguments different from its number of parameters. Lua adjusts
the number of arguments to the number of parameters by throwing away extra arguments and supplying
nils to extra parameters.

· When we use a call as an expression
(e.g., the operand of an addition), Lua keeps only the first result.
· We get all results only when the call is
the last (or the only) expression in a list of expressions.

print(foo2(), 1) -- a 1
print(foo2() .. 'x') -- ax

t = {foo0(), foo2(), 4} -- t[1] = nil, t[2] = "a", t[3] = 4

We can force a call to return exactly one result by enclosing it in an extra pair of parentheses.

ipairs{...}
local a, b = ...
local arg = table.pack(...) -- arg.n
select(2, "a", "b", "c") -- b c
select('#', a, b, c) -- 3

table.unpack
table.unpack({"Sun", "Mon", "Tue", "Wed"}, 2, 3) -- Mon Tue

io.input(filename)
io.output
避免 io.write(a..b..c)
print automatically applies tostring to its arguments

io.read
a reads the whole file
l drop newline read -- default
L read a line
n read a number
[*]num reads num chars as a string

io.lines()
table.sort

io.read(0) -- test for end of file
local n1, n2, n3 = io.read("n", "n", "n")

io.open -- nil 'error msg'

local f = assert(io.open(filename, "r"))
local t = f:read("a")
f:close()

io.stderr:write(message)
io.input() --
io.input():close()

for block in io.input():lines(2^13) do
io.write(block)
end

io.tmpfile -- read/write
io.flush()

setvbuf(mode[, bufsize])
no
full
line

f:seek(whence, offset)
set, cur, end
return current position of the stream, measured in bytes
from the beginning of the file.

function fsize (file)
local current = file:seek()
local size = file:seek("end")
file:seek("set", current)
return size
end

os.rename
os.remove

os.exit(true, true)
os.getenv("HOME")
os.execute -- true exit/signal return_status

f = io.popen(cmd, "w")
f = io.popen(cmd, "r)
f:close()
f:lines()

local to a control, function, chunk, then
do-end

strict.lua
raises an error if we try to assign to a non-existent global inside a function or to use a non-existent global.

local foo = foo

until terminates repeat structures

Lua has no switch statement

repeat–until statement repeats its body until its condition is true.

for var is local
do return end
::name::

table.sort(network, function (a,b) return (a.name > b.name) end)

Lib = {}
function Lib.foo (x, y) return x + y end

local fact
fact = function (n)
if n == 0 then return 1
else return n * fact(n-1)
end
end

do
Lua sandboxes
end

find, gsub, match, gmatch
string.find("a [word]", "[", 1, true) --> 3 3
string.gsub("all lii", "l", "x", 1)
When in doubt, play safe and use an escape.

balanced strings, %b()

%f[char-set]
string.gsub ("THE (QUICK) brOWN FOx JUMPS", "%f[%a]%u+%f[%A]", print)
"%f[%w]the%f[%W]" -- only as an entire word
d, m, y = string.match(date, "(%d+)/(%d+)/(%d+)")

_G

string.gsub(s, "\(%a+){(.-)}", "<%1>%2")

function toxml (s)
s = string.gsub(s, "\(%a+)(%b{})", function (tag, body)
body = string.sub(body, 2, -2) -- remove the brackets
body = toxml(body) -- handle nested commands
return string.format("<%s>%s", tag, body, tag)
end)
return s
end

print(toxml("\title{The \bold{big} example}"))
--> The <bold>big</bold> example

table.concat

print(string.match("hello", "()ll()")) --> 3 5

wday -- one is sunday
yday -- one is january 1st
isdst -- true is daylight saving is in effect

os.time({...})
os.date('*t', 0)
os.date("!%c", 0) -- utc
os.difftime
os.clock

bitwise operators only work on integer values

~ (bitwise exclusive-OR)

Lua does not offeran arithmetic right shift

a >> n is the same as a << -n

If the displacement is equal to or larger than the number of bits in the integer representation (64 in Standard
Lua, 32 in Small Lua), the result is zero, as all bits are shifted out of the result

he standard way to print numbers interprets
them as signed integers. We can use the %u or %x options in string.format to see integers as unsigned

math.ult

flip the signal bit of both operands
(0x7fffffffffffffff ~ mask) < (0x8000000000000000 ~ mask)

f = (u + 0.0) % 2^64 -- do not need 0.0

u = math.tointeger(((f + 2^63) % 2^64) - 2^63)

string.unpack("z", s, i) -- zero-terminated string

b (char),
h (short),
i (int), and l (long);
the option j uses the size of a Lua integer.

i1 - i16

s = table.concat(t, "\n") .. "\n"

string.format('%a', 1/3)
string.format("%q", a) -- works for nil and boolean

loadfile, dofile
f = load('i = i + 1')
-- load always compiles its chunks in the global environment.

A common mistake is to assume that loading a chunk defines functions
f = loadfile("foo.lua")
print(foo) --> nil
f() -- run the chunk
foo("ok") --> ok

luac -o prog.lc prog.lua

string.dump

pcall
xpcall -- debug.debug, debug.traceback

local f = require "mod".foo -- (require("mod")).foo

require

package.loaded
package.path

If require cannot find a Lua file with the module name,
it searches for a C library with that name.

package.cpath

package.loadlib

luaopen_modname

package.loaded[@rep{modname}]

local mod = require "mod".init(0, 0)

LUA_PATH_5_3 -> LUA_PATH -> compiled-defined default path
LUA_PATH_5_3 to "mydir/?.lua;; -- ;; 很重要
LUA_CPATH_5_3 or LUA_CPATH.
package.searchpath

lua -E

package.searchers
package.preload

package.loaded[...] = M

: if a module does not return a value, require will return the current value of
package.loaded[modname] (if it is not nil).

p -- p/init.lua
p.a -- p/a.lua luaopen_a_b

getmetatable
setmetatable

__metatable
__pairs
__index
mt.__index = prototype
rawget
__newindex
rawset(t, k, v)
local mt = {__index = function () return d end}
t[{}] = d

function Account:withdraw (v)
self.balance = self.balance - v
end

getmetatable(a).__index.deposit(a, 100.00)

rawset, which bypasses the metamethod

你可能感兴趣的:(Programming in Lua 4th Edition)