İşlev bağımsız değişkenleri için varsayılan değerleri tanımlayın


86

Lua wiki'de eksik argümanlar için varsayılan değerleri tanımlamanın bir yolunu buldum:

function myfunction(a,b,c)
    b = b or 7
    c = c or 5
    print (a,b,c)
end

Tek yol bu mu? PHP stili myfunction (a,b=7,c=5)çalışmıyor gibi görünüyor. Lua yöntemi işe yaramadığından değil, bunu yapmanın tek yolu bu mu diye merak ediyorum.

Yanıtlar:


87

Adlandırılmış bağımsız değişkenler ve PHP veya Python gibi varsayılan değerler istiyorsanız, işlevinizi bir tablo yapıcısı ile çağırabilirsiniz:

myfunction{a,b=3,c=2}

(Bu gibi Lua birçok yerde, görülür gelişmiş LuaSocket en protokol modülleri formları ve kurucular IUPLua .)

İşlevin kendisinin şu şekilde bir imzası olabilir:

function myfunction(t)
    setmetatable(t,{__index={b=7, c=5}})
    local a, b, c =
      t[1] or t.a, 
      t[2] or t.b,
      t[3] or t.c
    -- function continues down here...
end

Parametre tablosunda eksik olan tüm değerler __index, metatable tablosundaki tablodan alınacaktır (meta tablolarla ilgili belgelere bakın) ).

Tabi ki, tablo yapıcılarını ve fonksiyonlarını kullanarak daha gelişmiş parametre stilleri mümkündür - ihtiyacınız olanı yazabilirsiniz. Örneğin, burada , parametre adlarını ve varsayılan değerleri tanımlayan bir tablodan adlandırılmış veya konumsal bağımsız değişken tablolarını ve normal bir bağımsız değişken listesi alan bir işlevi oluşturan bir işlev oluşturan bir işlev vardır.

Dil düzeyinde olmayan bir özellik olarak, bu tür çağrılar yeni davranışlar ve anlambilim sağlamak için değiştirilebilir:

  • Birden fazla adı kabul edecek şekilde değişkenler yapılabilir
  • Konumsal değişkenler ve anahtar kelime değişkenleri arasına serpiştirilebilir ve her ikisini de tanımlamak, bunlardan birine öncelik verebilir (veya bir hataya neden olabilir)
  • Yalnızca anahtar kelimeden oluşan konumsuz değişkenlerin yanı sıra yalnızca adsız konum içeren değişkenler yapılabilir
  • Oldukça ayrıntılı tablo yapısı, bir dizeyi ayrıştırarak yapılabilir.
  • İşlev 1 tablodan başka bir şeyle çağrılırsa, argüman listesi kelimesi kelimesine kullanılabilir.

Argüman çevirmenleri yazmak için bazı yararlı işlevler unpack( table.unpack5.2'ye taşınıyor ), setfenv(5.2'de yeni _ENVyapıyla kaldırılmıştır ) ve select(verilen bir bağımsız değişken listesinden tek bir değer veya listenin uzunluğunu döndüren '#').


AI lua'yı kullanmaya yeni başladı Şimdilik basit tutacağım ama gönderiniz çok bilgilendirici. Daha sonra işe yarayabilir. Teşekkürler.
ripat

1
Çoğu durumda, gitmenin yolu basit tutmaktır. Meta parametre arabirimleri yalnızca çok sayıda isteğe bağlı özniteliğe (UI nesneleri gibi) sahip nesneler için gerçekten gereklidir.
Stuart P. Bentley

Sanırım bu cevap, şu anda kabul edildi olarak işaretlenen değil, soruları çözen cevaptır. Aydınlanma için teşekkürler :)
geri alın

2
Unutulmamalıdır x or defaultde bu cevapta kullanılan ifade parametre varsayılan gerçek eşdeğer ama hem yalnızca çalıştığını sadece basit bir çözüm gerçekten değil nilve falsegeçersiz parametre değerleridir. Bir boole parametresi için varsayılanın xolduğunu trueve çağıranın açık bir şekilde ilettiğini varsayalım false. Sonra , açıkça geçmesine rağmen x or trueverir . Daha iyi bir versiyon olurdu ve bu da daha okunabilirdir; yine de açık argümanları işleyemez . truefalseif x == nil then x = default endnil
Jesper

Oh, hey, şimdi kabul edilen cevap bu! Güzel. (Kayıt için ve @ Undo'nun yorumunu bağlama oturtmak için, jpjacobs'un aşağıdaki cevabı çok uzun bir süredir kabul edilen cevaptı: Üzerine neredeyse ikinci bir Popülist rozeti almıştım .)
Stuart P. Bentley

46

Bence başka bir yol yok. Bu sadece Lua zihniyetidir: fırfırlar yok ve bazı sözdizimsel şekerler dışında, basit şeyler yapmanın gereksiz yolları yok.


10
Bu cevap, Stuart P. Bentley'in aşağıdaki cevabı ile tamamen çürütülmüştür, burada fonksiyon bir tablo kurucusu ile çağrılır. Bu Lua'nın güçlü yönlerinden biridir: bir sürü fırfırına sahip olmasa da, Lua'nın temel yapı taşları, dilin küçük boyutu ve sadeliği için gerçekten dikkate değer olan sınırsız şeyler yapmanıza izin verir.
Colin D Bennett

@ColinDBennett Konuştuğunuz için teşekkürler: OP yorumunuzu okudu ve o Aralık ayında kabul edilen cevabı buna göre değiştirdi. (Ve şimdi "Stuart P. Bentley'in cevabı yukarıda", açıklık adına: göz kırp :)
Stuart P. Bentley

21

Teknik olarak, var b = b == nil and 7 or b( 7'ye göre değerlendirildiğinde falsegeçerli bir değer olduğu durumda kullanılmalıdır false or 7), ama muhtemelen aradığınız şey bu değil.


1
Kontrol etmiyorsanız false, daha basit bir yol, değişkeni önce ve varsayılanı son olarak koymaktır. b = b or 7
Rebs

2
OP, sorusunda bundan bahsettiğinden, bahsetmenin gereksiz olacağını düşündüm (soru, dışındaki varsayılan değişkenleri tanımlama yolları hakkındaydı b = b or 7).
Stuart P. Bentley

6

Şimdiye kadar mantıklı bulduğum tek yol, bunun gibi bir şey yapmak:

function new(params)
  params = params or {}
  options = {
    name = "Object name"
  }

  for k,v in pairs(params) do options[k] = v end

  some_var = options.name
end

new({ name = "test" })
new()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.