Lua Academy · Ders

__tostring ve __len

Dize gösterimini ve # operatörünü üst yöntemler aracılığıyla denetleyin.

4. ders / 412 adım

__tostring ve __len, CoddyKit'te ücretsiz bir Lua Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Lua Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Lua Academy kursu toplamda 4 dersten oluşur.

__tostring Metamethod'u

tostring(obj) çağrıldığında ve ayrıca print() tarafından (her bağımsız değişken üzerinde tostring çağırır) __tostring çağrılır. Özel nesnelerinizin insanlar tarafından okunabilir bir gösterimini sağlamak için bunu tanımlayın.

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)

Diziler için __len

Bu metamethod'a sahip bir tabloya # işleci uygulandığında __len çağrılır. Lua 5.2 ve sonraki sürümlerde __len tablolar için her zaman çağrılır; 5.1'de yalnızca userdata için çağrılır. Özel kapsayıcılar için "uzunluk" tanımlamak amacıyla kullanın.

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

Hata Ayıklama için Ayrıntılı __tostring

İyi bir __tostring, tür adını ve temel alanları içerir. İç içe nesneler için tostring işlevini özyinelemeli olarak çağırın. Bu, varsayılan "table: 0x..." çıktısına göre hata ayıklamayı çok daha kolaylaştırır.

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 ve # İşleci Karşılaştırması

__len metamethod'u olmayan tablolarda #t, dizinin herhangi bir sınırını bulur (t[i] ~= nil ve t[i+1] == nil olan yer). Tabloda boşluklar varsa sonuç öngörülemez. __len, güvenilir ve tutarlı bir uzunluk tanımlamanızı sağlar.

-- 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)

Hata İletilerinde __tostring

Hata nesneleri (dizgeler yerine tablolar) kullandığınızda __tostring tanımlanmışsa, hata yayıldığında ve bir dizgeye dönüştürüldüğünde hata iletileri okunabilir olur.

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...

Kalıtımla __tostring

Prototip tabanlı OOP kullanırken __tostring alanını sınıf metatable'ında tanımlayın. Örneğin metatable'ı sınıf tablosunun kendisi olduğundan tüm örnekler sınıfın __tostring alanını otomatik olarak kullanır.

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)

__len ve __tostring ile Küme Uygulama

Kullanıcı dostu ve eksiksiz bir Set uygulaması için __len ile __tostring alanlarını tek bir türde birleştirin.

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}

Her İkisini de İçeren Sayısal Nesneler

Görüntüleme için __tostring ve basamak sayısı (veya alana özgü bir ölçüt) için __len kullanan bir kesir türü oluşturun.

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/6

Varsayılan print Davranışını Geçersiz Kılma

Lua'nın print işlevi, her bağımsız değişken üzerinde tostring çağırır ve bunları sekmelerle ayırır. __tostring tanımlandığında nesneleriniz, tostring kullanan tüm print ifadelerinde, hata iletilerinde veya dizge araya eklemelerinde anlamlı biçimde görüntülenir.

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

Lua 5.3+ Sürümünde __name

Lua 5.3 ve sonraki sürümler, türü tanımlamak için varsayılan hata iletilerinde kullanılan bir __name alanını metatable'da destekler. Bu alan tostring() işlevini doğrudan etkilemese de tür üzerinde geçersiz işlemler yaptığınızda çalışma zamanı hata iletilerinde görünür.

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)

Hızlı Denetim

__tostring ne zaman çağrılır?

Özet: __tostring ve __len

Özet:

  • __tostring: tostring() ve print() tarafından çağrılır
  • __len: #obj tarafından çağrılır; özel kapsayıcılar için güvenilir uzunluk sağlar
  • Tüm örnekler için __tostring alanını sınıf tablolarında tanımlayın
  • Ham tablo yapısı doğru # sonucunu vermediğinde __len kullanın
  • __name (5.3+) hata iletilerinde türü adlandırır
Başlamak ücretsiz

Yapay zeka eğitmeniyle Lua öğren — ücretsiz

Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.

Kurslar
40
Dersler
159

Sıkça Sorulan Sorular

“__tostring ve __len” dersi ücretsiz mi?

Evet — “__tostring ve __len” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Lua Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Lua Academy kursu toplamda 4 dersten oluşur.

“__tostring ve __len” dersinde ne öğreneceğim?

Dize gösterimini ve # operatörünü üst yöntemler aracılığıyla denetleyin. Lua Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Lua Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Lua Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.

“__tostring ve __len” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Lua Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Lua Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Üst Tablolara Giriş
  2. __index ve __newindex
  3. Aritmetik Üst Yöntemleri
  4. __tostring ve __len
← Lua Academy Sayfasına Dön