[luau/en] Add Luau dcumentatin

This commit is contained in:
ratplier 2025-01-30 13:21:34 +08:00
parent 0dba59d585
commit a848a2e06b

509
luau.md Normal file
View File

@ -0,0 +1,509 @@
---
name: Luau
contributors:
- ["ratplier", "http://github.com/ratplier"]
filename: learnLuau.luau
---
**Luau** builds upon Lua 5.1, enhancing performance and adding features while maintaining broad compatibility.
This example explores core concepts and highlights distinctions between Luau and standard Lua 5.1.
```lua
-- Single line comment
--[[
Two sets of brackets create a multi-line comment
]]
--[=[
Adding equal signs between the brackets allows for nested multi-line comments.
]=]
--[==[
The above is matched in equal signs to the below, so it will not cause an error.
This allows for commenting out large blocks of code that contain multi-line comments.
]==]
-- Variables:
local a = 0
local x, y, z = 0, 0, 0 -- Multiple assignments
local z, x, y = x, y, z -- Variables are evaluated before assignment
local number = 0 -- Integer
local decimal = 220.022 -- Floating-point number
local hexadecimal = 0xAA -- Hexadecimal number
-- Arithmetic Operations:
number = number + 1
number = number - 1
number = number * 2
number = number / 2
number = number ^ 2
number = number % 2
-- Compound Assignment Operators:
-- Used as syntax sugar
-- works with all math operations
-- special exceptions are listed below
number += 1
number -= 1
number *= 1
number /= 1
number //= 1 -- Floor division (rounded down)
number %= 1 -- Modulus (or remainder)
number ^= 1 -- Exponent
-- Strings:
local helloString = "Hello"
local worldString = "World!"
local multiLineString = [[
This is a multi-line string.
It can span multiple lines.
]]
local interpolatedString = `var(number) -> {20}` -- var(number) -> 20
local concatenatedString = helloString .. worldString -- String concatenation
concatenatedString ..= multiLineString -- Concatenation compound operator
-- Lua (and Luau) use automatic garbage collection. Setting a variable to nil makes it
-- eligible for GC sooner, but isn't strictly necessary. It's mainly beneficial for
-- releasing large objects quickly or preventing accidental access to stale values. Values
-- are also GC'd when a scope (e.g., do-end block, function) ends.
-- More details: https://www.lua.org/wshop18/Ierusalimschy.pdf
multiLineString = nil -- No longer needed; allows quicker GC.
-- Booleans and Logical Operators:
local booleanValue = true
booleanValue = not booleanValue -- Flip boolean to false
local andResult = true and false -- Logical AND
local orResult = true or false -- Logical OR
local chainedResult = (true and false) or (true or not true) -- Chained expressions
-- Tables (Arrays and Dictionaries):
local emptyTable = {}
local myArray = { "index 1", "index 2", "index 3", [4] = "index 4" } -- Array
local dictionary = { key1 = 20, key2 = 30, key3 = 40 } -- Dictionary
local preAllocatedArray = table.create(20) -- Efficiently pre-allocate an array
local preFilledArray = table.create(20, "hello") -- Create and fill an array
emptyTable["a"] = 20 -- Add to table (dictionary style)
emptyTable.b = 10 -- Alternative syntax
emptyTable[1] = 30 -- Add to table (array style)
print(emptyTable[1]) -- Access array element
print(emptyTable["a"]) -- Access dictionary element
print(dictionary.key1) -- Access dictionary element
-- Table Library Functions:
local packedTable = table.pack(1, 2, 3) -- Pack values into an array
local anotherTable = table.create(3)
local val1, val2, val3 = table.unpack(packedTable) -- Unpack array into variables
table.insert(myArray, "hello") -- Insert at the end
table.insert(myArray, 1, "world") -- Insert at index 1
table.remove(myArray, 1) -- Remove element at index 1
local clonedTable = table.clone(myArray) -- Shallow copy
local arrayLength = table.maxn(myArray) -- Get array length (for numerically indexed tables)
table.sort(myArray, function(a, b) -- Sort with custom comparator
return a > b
end)
table.clear(emptyTable) -- Remove all elements
table.move(myArray, 2, 3, 1, anotherTable) -- Copy a section of array to another table
local concatenatedValues = table.concat(myArray, " ") -- Join array elements into a string
local readOnlyTable = table.freeze(myArray) -- Create a read-only version of the table (Luau Specific)
-- Functions:
local function add(a, b)
return a + b
end
local sum = add(2, 3)
local function average(...) -- Variadic function (accepts any number of arguments)
local args = table.pack(...)
local total = 0
for _, n in ipairs(args) do
total += n
end
return total / #args
end
local avg = average(10, 20, 30, 40)
-- Control Flow:
do
local myLocal = 20 -- Local scope
myGlobal = 10 -- Global scope
local myNilValue -- Declaring a nil variable (Luau allows this locally not globally)
myNilValue = 20
end
local counter = 0
while counter < 50 do
counter -= 1
counter += 2
end
while false do -- Never executes
print("This will not print")
end
if counter > 40 then
print(counter)
end
local loopCount = 0
repeat
loopCount += 1
until loopCount > 20
repeat
print("Hello (once)")
until true -- Only runs once
local age = 20
if age >= 18 then
print("Adult")
elseif age >= 13 then
print("Teenager")
else
print("Child")
end
-- For Loops:
for i = 1, 5 do
print(i)
end
for k = 10, 1, -2 do
print(k)
end
-- Generic For Loops (Iterators):
local dataTable = { a = 1, b = 2, c = 3 }
for key, value in pairs(dataTable) do -- Key-value pairs
print(key, value)
end
local numArray = { 10, 20, 30 }
for index, value in ipairs(numArray) do -- Numerically indexed arrays
print(index, value)
end
local mixedTable = { 10, 20, 30, a = 20 }
for index, value in next, mixedTable do -- For tables where the indexing type is unknown
print(index, value)
end
-- Custom Iterator:
local function customIterator(t, i)
i = i + 1
local v = t[i]
if v then
return i, v
end
end
local customTable = { 10, 20, 30 }
for index, value in customIterator, customTable, 0 do
print(index, value)
end
-- Luau specific features:
-- Buffers
-- Buffers are used for storing and manipulating raw binary data.
-- They are often used when dealing with network communication, file I/O, or when precise control over memory layout is needed.
-- Unlike strings which are UTF-8 encoded, buffers store raw bytes without any interpretation.
-- Creating Buffers:
local initialSize = 30
local myBuffer = buffer.create(initialSize) -- Create a buffer with an initial capacity of 20 bytes.
print("Initial buffer size:", buffer.len(myBuffer)) -- Output: 20
local myBuffer2 = buffer.create(5, 0xFF) -- create a buffer and prefill with the byte value 0xFF (255 in decimal)
print(
"Initial buffer size:",
buffer.len(myBuffer2),
" first byte: ",
buffer.readu8(myBuffer2, 0)
) -- Output: 5, 255
-- Writing Data to a Buffer:
buffer.writeu8(myBuffer, 0, 0x41) -- Write the byte 0x41 ('A') at index 0 (as an unsigned 8-bit int)
buffer.writeu16(myBuffer, 1, 0x1234) -- Write the 16-bit value 0x1234 at index 1 (as an unsigned 16-bit int, little-endian)
buffer.writeu32(myBuffer, 3, 0xABCDEF01) -- Write the 32-bit value at index 3 (unsigned 32-bit int, little-endian)
buffer.writef32(myBuffer, 7, 3.14) -- Write a 32-bit floating-point number (little-endian)
buffer.writef64(myBuffer, 11, 2.71828) -- Write a 64-bit floating-point number (little-endian)
buffer.writestring(myBuffer, 19, "Luau") -- Write a string at index 19
print("buffer after writing:", buffer.len(myBuffer)) -- output: 24
-- Reading Data from a Buffer:
local byte1 = buffer.readu8(myBuffer, 0) -- Read the byte at index 0
local short1 = buffer.readu16(myBuffer, 1) -- Read the 16-bit value at index 1
local int1 = buffer.readu32(myBuffer, 3) -- Read the 32-bit value at index 3
local float1 = buffer.readf32(myBuffer, 7) -- Read the 32-bit float
local double1 = buffer.readf64(myBuffer, 11) -- Read the 64-bit double
local str = buffer.readstring(myBuffer, 19, 4) -- Read the string from beginning to char 4
print("Read bytes:", string.format("0x%X",byte1) ) -- Output: 0x41
print("Read short:", string.format("0x%X",short1) ) -- Output: 0x1234
print("Read int:", string.format("0x%X",int1) ) -- Output: 0xABCDEF01
print("Read float:", float1) -- Output: 3.140000104904175
print("Read double:", double1) -- Output: 2.7182800000000001
print("Read string:", str) -- Output: Luau
-- Buffer Size and Capacity:
local currentSize = buffer.len(myBuffer) -- Get the current size (used bytes)
print("Current buffer size:", currentSize) -- Output: 24
-- Other Operations:
buffer.fill(myBuffer, 0, 0x00) -- Fill buffer with 0x00 starting from index 0
local newBuffer = buffer.create(currentSize) -- Create a buffer to copy to from another buffer
buffer.copy(myBuffer, 0, newBuffer, 5, 10) -- copy 10 bytes from myBuffer starting at 0 to newBuffer at index 5
print("Copied buffer:", buffer.readu8(newBuffer, 5)) -- read one of the bytes copied above
-- Error Handling:
local function tryRead(buf, index)
local success, value = pcall(buffer.readu8, buf, index)
if success then
print("Read byte at", index, ":", string.format("0x%X",value))
else
print("Error at index", index, ":", value)
end
end
tryRead(myBuffer, 31) -- this will error
tryRead(newBuffer, 6) -- this will be okay
-- Important Notes:
-- * Byte Order (Endianness): Luau buffers typically use little-endian byte order for multi-byte values (U16, U32, U64, F32, F64).
-- * Indexing: Buffer indices are 0-based. The first byte is at index 0.
-- * Error Handling: Attempting to read or write outside the bounds of a buffer can lead to errors, so handle these cases accordingly, consider `pcall` or manually handling it.
-- * Buffer usage is more memory efficient than string when dealing with large chunks of binary data.
-- Types
-- Types in Luau are used to define the kind of data a variable, function, or table can hold or return.
-- They improve code readability, prevent errors, and make development faster by enabling better tooling support.
-- Types can describe simple values like numbers or strings, as well as more complex structures like tables or functions.
-- Basic Types:
-- These are the most common types used in Luau.
local aNumber: number = 10 -- Represents numeric values (e.g., integers, floating-point numbers).
local aString: string = "Hello" -- Represents text or character sequences.
local aBoolean: boolean = true -- Represents true or false values.
local aNil: nil = nil -- Represents the absence of a value (or "nothing").
-- Compound Types:
-- Used to represent collections of values.
local aTable: table = {1, 2, 3} -- Can store arrays, dictionaries, or mixed data.
local aDictionary: { [string]: number } = { key1 = 10, key2 = 20 }
-- A table with string keys and number values.
-- Union and Optional Types:
-- Union types allow a variable to hold multiple possible types.
-- Optional types allow a variable to hold a specific type or nil.
local aUnion: string | number = 42 -- Can be a string or a number.
local anOptional: number? = nil -- Can be a number or nil.
-- Defining Types:
-- You can predefine types to be used locally or in other modules
type vector3 = {
x: number,
y: number,
z: number
}
local a: vector3 = {}
a.x = 20
-- Export a type for other modules to use
export type vector3 = vector3
-- Generic Types:
-- You can make types that take in types and return a new type
type array<T> = {T} -- basic array type
type dictionary<K, V> = {[K]: V}
type recursiveType<T> = {
head: recursizeType<T>?,
value: T,
}
-- Function Types:
-- Functions can also have types to define their inputs and outputs.
local function sub(x: number, y: number): number
return x + y
end
-- You can also do it like this
local add: (number, number) -> number = function(x, y)
return x + y
end
-- basic function type definition
type callback<...I, ...O> = (I...) -> (O...)
local function addVec3(a: vector3, b, vector3): vector3
return {
a.x + b.x,
a.y + b.y,
a.z + b.z,
}
end
local function myTypedFunction<A>(parameter: A): A
print(A)
return A
end
-- Metamethods and Metatables
-- Metatables allow you to customize the behavior of tables. They provide a mechanism
-- to intercept operations like addition, indexing, function calls, etc. Metamethods
-- are functions defined within the metatable that are triggered when these operations
-- are performed on a table associated with that metatable.
-- Example: Overloading the addition operator (+)
local mt = {} -- Create a metatable
mt.__index = mt -- Make methods self-referencing
mt.__add = function(self, other) -- Define the __add metamethod
return self.value + other.value
end
local t1 = { value = 10 }
local t2 = { value = 20 }
setmetatable(t1, mt) -- Assign the metatable
setmetatable(t2, mt)
local sum = t1 + t2 -- Calls the __add metamethod
print(sum) --> 30
-- Other common metamethods:
-- __index: For handling table lookups (when a key doesn't exist).
-- __newindex: For handling table assignments.
-- __call: For making tables callable like functions.
-- __len: For getting the length of a table.
-- __idiv: Integer division in Luau.
-- etc. (See Lua/Luau documentation for a complete list)
-- at https://create.roblox.com/docs/luau/metatables
-- Native Code Generation (NCG)
-- Luau's NCG compiles Lua code directly into native machine code, leading to significant
-- performance improvements compared to interpreted Lua. NCG leverages LLVM to
-- optimize the generated code further. Not all platforms support NCG.
-- Code Optimization (Luau)
-- Luau provides various optimization techniques:
-- * Loop unrolling: Reduces loop overhead for small, fixed iterations.
-- * Constant folding: Evaluates constant expressions at compile time.
-- * Inlining: Replaces function calls with the function's body in some cases.
-- * Dead code elimination: Removes code that is never executed.
-- * String interning: Stores identical strings only once, saving memory.
-- * Efficient table implementation: Luau's table implementation is optimized for
-- common usage patterns.
-- * Type specialization (Luau): When type information is available, Luau can generate
-- more efficient code tailored to specific types.
-- These optimizations, combined with NCG, contribute significantly to Luau's performance advantages over standard Lua 5.1.
-- End of Luau Showcase
```
## Lua Libraries in Luau and Differences:
Most Lua 5.1 libraries are present in Luau (e.g., `math`, `string`, `table`, `coroutine`). However, there are some key differences:
* `io` (restricted): Limited or no access to file system functions due to sandboxing.
* `os` (mostly absent): Operating system specific functions are generally unavailable.
* `debug` (limited): Debugging functionality may be curtailed.
* `package` (modified): Luau's module system may have significant changes depending on the embedding platform (e.g., Roblox).
## Luau Specific Libraries
* `bit32`: Bitwise operations library similar to Lua 5.2's `bit32`
* `utf8`: If supported, provides UTF-8 string handling functions