__tostring dan __len
Kawal perwakilan rentetan dan operator # melalui kaedah meta.
__tostring dan __len ialah pelajaran Lua Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Lua Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Lua Academy merangkumi sejumlah 4 pelajaran.
Kaedah Metameta __tostring
__tostring dipanggil apabila tostring(obj) digunakan, dan juga oleh print() (yang memanggil tostring pada setiap argumen). Takrifkannya untuk menyediakan perwakilan objek tersuai anda yang boleh dibaca manusia.
local Point = {}
Point.__index = Point
Point.__tostring = function(p)
return string.format("Point(%.2f, %.2f)", p.x, p.y)
end
function Point.new(x,y)
return setmetatable({x=x,y=y}, Point)
end
local p = Point.new(3.14, 2.72)
print(p) -- Point(3.14, 2.72)
print(tostring(p)) -- Point(3.14, 2.72)__len untuk Jujukan
__len dipanggil apabila operator # digunakan pada jadual yang mempunyai kaedah metameta ini. Dalam Lua 5.2+, __len sentiasa dipanggil untuk jadual; dalam 5.1, ia hanya dipanggil untuk data pengguna. Gunakannya untuk mentakrifkan "panjang" bagi bekas tersuai.
local Queue = {}
Queue.__index = Queue
Queue.__len = function(q) return q._tail - q._head + 1 end
function Queue.new()
return setmetatable({_data={},_head=1,_tail=0}, Queue)
end
function Queue:push(v)
self._tail = self._tail + 1
self._data[self._tail] = v
end
function Queue:pop()
if self._head > self._tail then return nil end
local v = self._data[self._head]
self._head = self._head + 1
return v
end
local q = Queue.new()
q:push("a"); q:push("b"); q:push("c")
print(#q) -- 3__tostring Terperinci untuk Penyahpepijatan
__tostring yang baik merangkumi nama jenis dan medan utama. Untuk objek bersarang, panggil tostring secara rekursif. Ini menjadikan penyahpepijatan jauh lebih mudah berbanding output lalai "table: 0x...".
local function tableToString(t, depth)
depth = depth or 0
if depth > 3 then return "{...}" end
local parts = {}
for k, v in pairs(t) do
if type(v) == "table" then
parts[#parts+1] = k.."="..tableToString(v, depth+1)
else
parts[#parts+1] = k.."="..tostring(v)
end
end
return "{"..table.concat(parts,", ").."}"
end
local obj = {name="test", data={x=1,y=2}, active=true}
print(tableToString(obj))__len berbanding Operator #
Bagi jadual tanpa kaedah metameta __len, #t mencari mana-mana sempadan jujukan (apabila t[i] ~= nil dan t[i+1] == nil). Jika terdapat lompang dalam jadual, hasilnya tidak dapat diramal. __len membolehkan anda mentakrifkan panjang yang muktamad dan konsisten.
-- Table with hole: # is unpredictable
local t = {10, 20, nil, 40}
print(#t) -- could be 2 or 4, undefined!
-- Custom container with authoritative length
local SafeList = {}
SafeList.__index = SafeList
SafeList.__len = function(s) return s._size end
function SafeList.new()
return setmetatable({_data={}, _size=0}, SafeList)
end
function SafeList:add(v)
self._size = self._size + 1
self._data[self._size] = v
end
local s = SafeList.new()
s:add(1); s:add(nil); s:add(3)
print(#s) -- 3 (always correct)__tostring dalam Mesej Ralat
Apabila anda menggunakan objek ralat (jadual dan bukannya rentetan), mentakrifkan __tostring menjadikan mesej ralat mudah dibaca apabila ralat itu merambat dan ditukar kepada rentetan.
local function makeError(code, msg)
return setmetatable(
{code=code, message=msg},
{__tostring = function(e)
return string.format("Error[%d]: %s", e.code, e.message)
end}
)
end
local ok, err = pcall(function()
error(makeError(404, "resource not found"))
end)
if not ok then
-- err is the error object (table)
print(tostring(err)) -- may show table address...__tostring dengan Pewarisan
Apabila menggunakan OOP berasaskan prototaip, takrifkan __tostring pada metajudual kelas. Semua tika akan menggunakan __tostring kelas secara automatik kerana metajudual tika IS jadual kelas.
local Animal = {}
Animal.__index = Animal
Animal.__tostring = function(a)
return string.format("%s(%s)", a._type or "Animal", a.name or "?")
end
function Animal.new(name, atype)
return setmetatable({name=name, _type=atype}, Animal)
end
local cat = Animal.new("Whiskers", "Cat")
local dog = Animal.new("Rex", "Dog")
print(cat) -- Cat(Whiskers)
print(dog) -- Dog(Rex)Melaksanakan Set dengan __len dan __tostring
Gabungkan __len dan __tostring dalam satu jenis untuk pelaksanaan Set yang lengkap dan mesra pengguna.
local Set = {}
Set.__index = Set
Set.__len = function(s) return s._size end
Set.__tostring = function(s)
local items = {}
for k in pairs(s._data) do items[#items+1]=tostring(k) end
table.sort(items)
return "Set{" .. table.concat(items,", ") .. "}"
end
function Set.new(...)
local obj = setmetatable({_data={},_size=0}, Set)
for _, v in ipairs({...}) do
if not obj._data[v] then obj._data[v]=true; obj._size=obj._size+1 end
end
return obj
end
local s = Set.new(3,1,4,1,5,9,2,6)
print(#s) -- 7 (duplicates removed)
print(tostring(s)) -- Set{1, 2, 3, 4, 5, 6, 9}Objek Berangka dengan Kedua-duanya
Cipta jenis pecahan dengan __tostring untuk paparan dan __len sebagai kiraan digit (atau metrik khusus domain).
local Frac = {}
Frac.__index = Frac
local function gcd(a,b) return b==0 and a or gcd(b,a%b) end
function Frac.new(n,d)
local g = gcd(math.abs(n), math.abs(d))
return setmetatable({n=n//g, d=d//g}, Frac)
end
Frac.__tostring = function(f)
if f.d==1 then return tostring(f.n) end
return f.n .. "/" .. f.d
end
Frac.__add = function(a,b)
return Frac.new(a.n*b.d + b.n*a.d, a.d*b.d)
end
local a = Frac.new(1,2)
local b = Frac.new(1,3)
print(a + b) -- 5/6Mengatasi Tingkah Laku print Lalai
print Lua memanggil tostring pada setiap argumen yang dipisahkan oleh tab. Dengan __tostring ditakrifkan, objek anda dipaparkan dengan bermakna dalam mana-mana pernyataan cetakan, mesej ralat atau interpolasi rentetan yang menggunakan tostring.
local Color = {}
Color.__index = Color
Color.__tostring = function(c)
return string.format("#%02X%02X%02X", c.r, c.g, c.b)
end
function Color.new(r,g,b)
return setmetatable({r=r,g=g,b=b}, Color)
end
local red = Color.new(255,0,0)
local green = Color.new(0,255,0)
local blue = Color.new(0,0,255)
print(red, green, blue)
-- #FF0000 #00FF00 #0000FF__name dalam Lua 5.3+
Lua 5.3+ menyokong medan __name dalam metajudual, yang digunakan oleh mesej ralat lalai untuk mengenal pasti jenis. Walaupun ia tidak mempengaruhi tostring() secara langsung, medan ini muncul dalam mesej ralat masa jalan apabila anda melakukan operasi tidak sah pada jenis tersebut.
local MyType = {}
MyType.__index = MyType
MyType.__name = "MyType" -- used in error messages
MyType.__tostring = function(t)
return "MyType(" .. tostring(t.value) .. ")"
end
local obj = setmetatable({value=42}, MyType)
print(obj) -- MyType(42)
-- Error message will say "MyType" instead of "table"
-- pcall(function() local x = obj + 1 end)Semakan Pantas
Bilakah __tostring dipanggil?
Imbas Kembali: __tostring dan __len
Ringkasan:
__tostring: dipanggil olehtostring()danprint()__len: dipanggil oleh#obj; menyediakan panjang muktamad untuk bekas tersuai- Takrifkan
__tostringpada jadual kelas untuk semua tika - Gunakan
__lenapabila struktur jadual mentah tidak memberikan#yang betul __name(5.3+) menamakan jenis dalam mesej ralat
Pelajari Lua dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 40
- Pelajaran
- 159
Soalan Lazim
Adakah pelajaran “__tostring dan __len” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Lua Academy, termasuk “__tostring dan __len”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Lua Academy merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “__tostring dan __len”?
Kawal perwakilan rentetan dan operator # melalui kaedah meta. Anda berlatih Lua Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Lua Academy?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Lua Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.
Berapa lamakah pelajaran “__tostring dan __len” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Lua Academy ini?
Ya. Setiap pelajaran Lua Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Pengenalan kepada Metajadual
- __index dan __newindex
- Kaedah Meta Aritmetik
- __tostring dan __len