Lua言語とCorona SDK(2/3パート)

画像



これは、 Corona SDKの Lua言語の基本概念に関する記事の3つのパートの2番目です( 最初のパートを読んでいない場合は、 最初に読むことをお勧めします)。このパートでは、言語のすべてのデータ型を検討します。 すべてのタイプの変数を初期化し、それらの値を使用して、あるタイプを別のタイプに変換する方法を学習します。 この記事は言語学習の点で非常に重要であり、ゲームを書く際に多くの間違いを避けることができる貴重なヒントを多数追加しようとしました。



データ型とその変換



Luaには8つのデータ型があります。 型を検討する前に、lua言語の標準機能である型に注目します。 この関数は、指定された変数またはデータのデータ型の名前を含む文字列を返します。 型関数の使用例:



n = nil st = '' pi = 3.14 func = function()end t = {} b = true co = coroutine.create(function ()end) print(type(n), type(st), type(pi), type(func), type(t), type(b), type(co)) --: nil string number function table boolean thread
      
      





次に、この言語Luaのタイプを検討します。



タイプnil



デフォルトでは、このデータ型には値が割り当てられていない変数があります。 タイプnilのすべての変数の値はnilです。 このタイプは、次の2つの方法で変数に割り当てることができます。



 local B = nil--   local A--    -- -        nil
      
      





変数が現在のスコープで初期化されていない場合、その型と値はnilになることに注意してください。 タイプnilの変数は、論理演算ではなく値falseを持つ論理変数の比較の順序で比較できますが、実際にはこれらのタイプは類似していないため、例を示します。



 n = nil b = false if not n then--true print(1) end if not b then--true print(2) end if b == n then--false print(3) end -->> 1 -->> 2
      
      





ブール型



ブール型は、比較演算を実装するため、論理型またはブール型とも呼ばれます。 前述のように、ブールにはfalseとtrue( falseとtrue )の2つの値のみがあります 。 すべての比較演算はこれらの値を正確に返すため、このタイプの変数は比較演算の値を割り当てることで初期化できますが、値を直接割り当てることで初期化することもできます。 ブール型の変数は、等号および不等号の操作、およびif / elseifの比較条件とのみ直接比較できます。



 --    b1 = false b2 = true --   b3 = b1 ~= b2--true b4 = b1 == b2--false if b1 == b3 then--true print(true) end if b3 then print(true) end
      
      





型番



拡張された数値タイプの完全な説明は、このテキストの範囲を大きく超えているため、好奇心itive盛なユーザーはリンクをたどり、仕様を詳細に理解できます。 私は、整数と浮動小数点の両方の負数と正数の両方がこのタイプに対応できると言うことができます。特定のレベルの正と負のビットでは、指数形式の数値への自動遷移がありますが、ビット制限はデバイスのプロセッサのビット容量に依存しますが、現時点ではCorona SDKはAndroid 4.0.3以降をサポートしています 。これは、ほとんどの場合、利用可能なすべてのデバイスが64ビットになることを意味します。 数値型の変数を初期化するには、使用可能な形式のいずれかで値を明示的に割り当てるか、計算結果に変数を割り当てるか、この型の別の変数と同等にするだけで十分です。 論理比較の操作で型番号の変数はすべて0(および-1)でもtrueを返すことに注意してください。これは、c ++言語( など )のファンが考慮する必要があります(0はfalseに類似しています)。 タイプ番号を使用した操作の例を示します。



 local a,b = 2,3--  local c = a + b--   --   d = 12e5 -- 1 200 000 e = 2e-3 -- 0.002 --   f = 0x234 -- 564 --  j = 1.23 k = .55 -- 0.55 -    1      
      
      





タイプ番号の変数を使用すると、多くの数値演算を実行できます。その主な例を以下に示します。



 a = b + c --  a = b - c -- a = b * c --  a = b / c --  a = b % c --    a = b ^ c -- b   c
      
      





タイプ文字列



String型はLuaで非常によく開発されており、この型の変数を備えた多くの機能を備えています。 文字列型の変数を作成する方法:



 local st1 = 'qwert'--  st2 = st1--   st3 = st1 .. st2--   
      
      





例から気づいたように、文字列の連結は 2つのポイントによって実行されます。さらに、連結プロセス自体は、数値を文字列に変換する方法の1つとして使用できます。例を挙げます。



 i = 10--number st = '11'--string konc1 = 1 .. st --  konc2 = 100..''--       string print(konc1, konc2, type(konc1) , type(konc2 )-->>111 100 string string
      
      





ご覧のとおり、数値から文字列への変換は非常に簡単です。 ラインカップリングを使用する場合、クラッチ演算子とオペランドの間にスペースを入れるのが最善であることに注意してください。これは必ずしも必要ではありませんが、最初はとても美しく明確であり、次にオペランドの1つであるため、 -数字(数字と等しい変数、つまり数字で はありません )、スペースを入れないと、「 不正な形式の数字が近くにあります」というエラーが発生します。 変換するための従来のアプローチがありますが、両方向の翻訳の例を示します。



 i1 = 1 s1 = '11' i2 = tonumber(s1)-- string -> number s2 = tostring(i1)--  number -> string
      
      





また、文字列から数値への暗黙的な変換も存在することを付け加えますが、これを行わないことを強くお勧めします-それは完全にいものであり、いつの日か複雑なエラーにつながるでしょう:



 --      st = '10' i = 10 + st print(i, type(i))-->> 20 number
      
      





文字列型の変数を初期化すると、複雑なモーメントが発生することがよくあります。これについて簡単に説明し、それらを解決する方法を示します。





上で書いたように、stringには多くの便利なアメニティが含まれています。それらは以下で説明する関数を使用して実装されます。



string.len(s)/ s:len()



この関数を使用すると、文字列の長さを決定できます。 これは、 文字列ライブラリの他のほとんどの関数と同様に、2つの方法で使用できますが、以下の機能の例があります。使用例を以下に示します。



 --  string.len(s) local st = 'Hello World!' local len_st = string.len(st) print(len_st)-->>12 --  s:len() local le_st = st:len() print(len_st)-->>12 --    print(string.len('Examlpe string'))-->>14 --   -    --      print('Examlpe string':len())-->> Error: ')' expected near ':'
      
      





おそらくお気づきのように、関数を使用する方法は間違っています。コメントはエラーの本質を説明しています。 関数を使用するためのルールは、ライブラリの他のすべての関数に共通であるため、今後はこれについて詳しく説明しません。



string.byte(s [、i [、j]])/ s:バイト([i [、j]])



この関数は、i番目からj番目までの文字列の文字コードを返します。 パラメータiとjはオプションです。jを指定しない場合、i番目の要素のコードのみが返されます。iを指定せずにjを指定すると、最初からj番目の文字コードが返されます。文字列の最初の文字のコード。 関数の使用例を示します。



 local s = 'Example' print(s:byte())--  >> 69 print(string.byte(s, 3))--  >> 97 print(string.byte(s,nil, 4))--   4- >> 69 120 97 109 print(s:byte(nil, s:len()))--  >> 69 120 97 109 112 108 101
      
      





string.char(i1、i2、...)



この関数には、文字番号を持つ1つ以上のパラメーターが渡され、送信されたすべての文字に等しい文字列が返されます。 この関数は、string.char()関数に関して反対の目的を持っています。 使用例:



 print(string.char(65)) -->> A print(string.char(72,101,108,108,111)) -->> Hello local s = 'Example' print(string.char(s:byte(1,s:len())))-- s:byte   --- st        >> Example
      
      





string.find(s、パターン[、インデックス[、no_regular]])

s:検索(パターン[、インデックス[、no_regular]])



検索機能を使用すると、文字列sでパターンpatternの位置を検索できます。見つからない場合はnilを検索できます。 パターンは、文字列または正規表現のいずれかです別の章で正規表現の詳細を学習します )。 findの最も簡単なユースケースを検討し、次にオプションのパラメーターの機能に移りましょう。



 local s = "Hello Lua!" print(string.find(s,"Lua"))--      --  Lua   s >> 7 9 print(s:find("%sL"))--    " -- L       " >> 6 7
      
      





インデックスパラメータはデフォルトで1です。これは、最初から検索する場合、最初に見つかったエントリの位置が返されることを意味します。インデックスを例3に設定すると、文字列の3番目の出現が先頭から返されます。行末。 no_regularパラメーターは論理的です。 true / false(true / false)を指定できます。デフォルトではパラメーターはfalseです。trueに設定すると、パターンパラメーターは、正規表現を入力した場合でも常に正規の文字列として認識されます。 findの拡張使用の例を次に示します。



 s = 'La La La La %sLa La' print(s:find('La', 2)) --    >> 4 5 print(s:find('La', -2)) --    >> 18 19 print(s:find('%sLa', 1, true)) -->>  ,    >> 13 16
      
      





string.format(s、e1、e2、...)

s:形式(e1、e2、...)



string.format関数は、一連の引数を持つフォーマットされた文字列を作成します。 一見すると、この関数は理解しにくいように思えるかもしれませんが、実際には、最終情報を表示するときに多くの構造を大幅に簡素化できます。また、たとえば、数値から16進コードのストリングへのその他の間接的な変換にも非常に便利です。 最も簡単な例を挙げます。



 local sum1,sum2 = 100,200--   print(string.format('Value1: %d, Value2: %d', sum1,sum2))-->> Value1: 100, Value2: 200
      
      





ご覧のとおり、最初に行形式があります。この形式には、このパラメーターに続くパラメーターの使用方法を示す引数が含まれています。 数値を管理するための引数は11( c、d、E、e、f、g、i、o、u、X、x文字列を管理するための引数は2( s、q )です。 次に、各引数について簡単に説明し、その後で使用例を示します。





 print(string.format('Number: %d, Signed: %i, Unsigned: %u', 100,-100,-200)) -->> Number: 100, Signed: -100, Unsigned: 4294967096 print(string.format("%c%c%c%c%c%c%c", 69,120,97,109,112,108,101)) -->> Example print(string.format("%e, %E", math.pi,math.pi))-->> 3.141593e+000, 3.141593E+000 print(string.format("%f, %g", math.pi,math.pi))-->> 3.141593, 3.14159 print(string.format("%o, %x, %X", 1024,4069,16382)) -->> 2000, fe5, 3FFE print(string.format("%s %q", "Hello", "Corona SDK!"))-->> Hello "Corona SDK!"
      
      





string.lower(s)/ s:lower()



この関数は、文字列のすべての文字を小文字に変換します。



 print(string.lower('Hello World!')) -->> hello world!
      
      





string.upper(s)/ s:上部()



この関数は、文字列のすべての文字を大文字に変換します。



 print(string.upper('Hello World!')) -->>HELLO WORLD!
      
      





string.rep(s、n)/ s:rep(n)



関数には文字列と数値nが渡され、文字列はn回繰り返されます。



 local s = 'Corona ' print(s:rep(3))-->> Corona Corona Corona
      
      





string.reverse(s)/ s:reverse()



この関数は、文字の逆順で渡された文字列を返します。



 print(string.reverse('9876543210')) -->0123456789
      
      





string.match(s、パターン[、インデックス])

s:一致(パターン[、インデックス])



string.match関数は、正規表現パターンに従ってstring内のエントリを検索し、キャプチャパラメーターを返します。 正規表現のキャプチャについては、対応するセクションで詳しく説明します。 この関数にはオプションのパラメーターインデックスがあり、これはデフォルトで1に等しく、どのアカウントからパターンをキャプチャするかを決定します; string.findと同様に、負のインデックス値はサポートされていないことに注意してください:



 local reg = " (%w+):(%d+)"--    2  local s = " force:30, speed:25"--     local key, value = s:match(reg, 2)--    print(key, value)-->> speed 25
      
      





string.gmatch(s、パターン)

s:gmatch(パターン)



string.gmacth関数は、多くの点でstring.macth関数に似ていますが、ループの引数として使用することを目的としています(ループの詳細については、対応するセクションで説明します)。 string.gmacthは、文字列内のすべての出現からのキャプチャを周期的に返します。 インデックスは必須ではありません。次の例のようになります。



 local reg = " (%w+):(%d+)"--    2  local s = " force:30, speed:25"--     for key, value in s:gmatch(reg) do--     print(key, value) end -->> force 30 -->> speed 25
      
      





ループバックはLuaの最も強力なツールです。ループバックを使用できることにより、複雑な文字列値を解析するための多くのルーチン操作が大幅に容易になります。



string.sub(s、i [、j])

s:sub(i [、j])



string.sub関数は、渡された文字列の部分文字列を返します。 部分文字列は、i番目の文字で始まります。 3番目の引数jが指定されていない場合、サブストリングは行末で終了します。 3番目の引数が指定されている場合、サブストリングはj番目の文字で終了します。 iまたはjの値が負の場合、カウントは行の最後から始まります。 使用例を示します。



 local s = 'To be or not to be' print(s:sub(7))-->>or not to be print(s:sub(7,12))-->>or not print(s:sub(-5))-->>to be print(s:sub(4,-3))-->>be or not to print(s:sub(-8,-4))-->>ot to
      
      





string.gsub(s、パターン、置換[、n])

s:gsub(パターン、[、n]を置換)



string.gsub関数は、最も強力な言語関数の1つです。 この関数には、最も単純な場合にいくつかのアプリケーションがあります。文字列sのパターンで指定されたすべての一致を、すべての場所でreplaceで指定された値に置き換えます.nを使用して、置換の数を制限でき、関数は結果の文字列と置換の数を返します:



 local s = 'dust ist fantastisch' print(s:gsub('s','S'))-->>duSt iSt fantaStiSch 4 local s = 'lalalalala' print(s:gsub('a','A',3))-->>lAlAlAlala 3
      
      





string.findと同様に、正規表現(キャプチャ)を検索パターンとして使用できます。 キャプチャ引数は、index%index_numberに従って配置できます。



 print(string.gsub("lalalalala", "(l)(a)", "%2%1")) --  l  a --      -->> alalalalal 5
      
      





関数は置換パラメーターとして使用できますが、正規表現によってキャプチャーされたパラメーターはパラメーターとして渡されます。



 string.gsub("12 23 34", "(%d+)", print)--     -->> 12 -->> 23 -->> 34
      
      







utf-8について一言。



このため、文字列ライブラリのほとんどの関数はutf-8形式で正しく動作できません。これは、国別エンコードやその他の特殊文字を含む文字列が正しく処理されないためです。 これらの問題を解決するために、Corona SDKには個別のutfライブラリがあります。これには、文字列ライブラリの機能の類似物とそのいくつかの機能があります。 詳細については、このライブラリはCorona SDKの学習のコンテキストで検討されますが、読者は独自に学習することもできます。



タイプ表



テーブルタイプは、Luaのデータ表現の最も基本的なタイプであり、最も一般的な意味では、言語のほとんどすべての主要なエンティティはテーブルであり、ソースファイルです。 テーブルの作成方法とそれらの操作方法:



 local t = {}--   t['key1'] = 'name1'--  key1   "name1" t['key2'] = {}--  key2   t['key2']['key3'] = 123--  key3   key2
      
      





まったく同じテーブルを別の方法で初期化できます。



 local t = { key1 = 'name1', key2 = { key3 = 123, }, }
      
      





これらのエントリは同一であることに注意してください。



 t['key1'] = 'name1' t.key1 = 'name1'
      
      





最初のタイプのレコードの意味は、数値がキーとして使用される場合にのみ存在します。



 t[1] = 111--  t.1 = 111--   
      
      





表に記録されている値は、読み取りおよび書き込みに使用できます。



 print(t.key1)-->> name1 t.key1 = 'name2' print(t.key1)-->> name2
      
      





テーブルの内容全体をクリアするには、次のいずれかの方法を使用できます。



 t = {}--   -     table.remove(t)--    
      
      





テーブルキーの1つを削除する場合は、次の2つの方法があります。



 t.key1 = nil-- nil   table.remove(t, key1)--    
      
      





Luaでテーブルを初期化する最も自然な方法は、番号付き配列を作成することです。これは次の方法で行われます。



 local t = {23, 45, 3.14, 'vasia', {12, 'a'}}
      
      





実際、テーブルの初期化中にキーを指定しない場合、番号付けは1から始まる昇順で行われます(ほとんどの開発者にとって、0からの番号付けはより自然ですが、Luaではそうではないので、これを覚えておく必要があります)。 初期化されたテーブルは、実際には次のようになります。



 local t = { [1] = 23, [2] = 45, [3] = 3.14, [4] = 'vasia', [5] = { [1] = 12, [2] = 'a', }, }
      
      





ご覧のとおり、データの「裏側」では、非常に重要な変換が行われています。 Luaの番号付きテーブルには特別なプロパティがあります。たとえば、テーブル名に#記号を追加すると、テーブル内の厳密に番号付けされた値の数が取得されます。



 print(#t)-->>5 print(#t[5])-->>2 (     5)
      
      





#から取得した厳密に番号付けされた新しいキーをテーブルに追加すると、テーブルのサイズが増加します。



 t[#t+1] = 'kolia' print(#t)-->> 6
      
      





たとえば、nilを割り当ててキーの1つを削除すると、キー[3]番号付き配列の連続部分は2つのキー[1]と[2]に削減され、誤解によるさらなるエラーにつながることはありません。 table.removeを使用してテーブルからキーを削除します。キーを削除すると、残りの厳密に番号付けされた値がシフトされるためです。



 --   t[3] = nil print(#t)-->> 2 --   table.remove(t,3) print(#t)-->> 5
      
      





キーが正しく削除されると、テーブルは次のようになります。



 local t = { [1] = 23, [2] = 45, [3] = 'vasia', [4] = { [1] = 12, [2] = 'a', }, [5] = 'kolia', }
      
      





厳密に番号付けされたテーブルに他の番号なしキーを追加できますが、これはテーブルのパフォーマンスに影響しませんが、#でサイズを取得するときにこれらのキーも考慮されません。



 t.key = 'name1' print(t.key, #t)-->> name1 5
      
      





循環操作でテーブルのすべての番号付き値をバイパスするには、ipairs関数があります。これは、string.gmatchと同様に、forループの引数として使用されます。



 for key, value in ipairs(t) do print(key, value) end -->> 1 23 -->> 2 45 -->> 3 vasia -->> 4 table: 00000000 -->> 5 kolia
      
      





厳密に番号付けされていない値を含む、すべての値をループする場合は、ペア関数を使用します。



 for key, value in pairs(t) do print(key, value) end -->> 2 45 -->> key name1 -->> 3 vasia -->> 1 23 -->> 4 table: 00000000 -->> 5 kolia
      
      





注意してください? ペアを使用する場合、出力値のシーケンスは厳密ではありませんが、一般的には混乱を招くため、これを考慮する必要があります。 結論として、ペア/ ipairsを使用すると、テーブルの値を渡すか、次のような呼び出しで直接作成することができます。



 for key, value in ipairs{10,20,30} do print(key, value) end -->> 1 10 -->> 2 20 -->> 3 30 for key, value in pairs{key1 = 34,key2 = 65, key3 = 12} do print(key, value) end -->> key1 34 -->> key3 12 -->> key2 65
      
      





型関数



関数タイプには、すべてのユーザー作成関数と標準言語関数があります。 例を挙げます。



 local summ = function(a,b) return a + b end print(type(summ))-->> function print(type(print))-->> function
      
      





関数の適用については、対応するセクションで詳しく学習します。



タイプスレッド



スレッドは独立したコード実行スレッドです。 それが何であるかを簡単に説明しようとします。 Luaプロジェクトのすべてのコードは、単一の実行スレッドで実行されます。別のスレッドで実行する必要がある場合、threadタイプのオブジェクトが作成されます。 次のコードを使用して作成します。



 --  local co = coroutine.create(function () --    end) print('TYPE: '..type(co))-->> thread
      
      







ご覧のとおり、スレッドタイプのオブジェクトですが、実際にはコードは実行されていないため、これを修正するには、coroutine.resumeを呼び出してスレッドオブジェクトを渡す必要があります。コードの実行プロセスでは、実行を中断し、しばらくしてから同じ場所から実行を継続する必要がある場合があります。関数coroutine.yield()は、関数の状態を維持しながら実行を終了するために使用され、スレッド関数の本体内のパラメーターなしで実行されます。コードの実行に戻るには、coroutine.resumeを再実行する必要があります。サブプログラムの本体にカウンターを含む永遠のサイクルが含まれる例を作成してみましょう。各反復で、ルーチンはサブプログラムを終了します。すなわち コードは、このオブジェクトに対してcoroutine.resumeが実行された回数を実際にカウントします。



 --  local co = coroutine.create(function () local num = 1--     while true do print(num)--   num = num + 1-- coroutine.yield()--   resume end end) print('TYPE: '..type(co)) --     coroutine.resume(co)-->> 1 coroutine.resume(co)-->> 2 coroutine.resume(co)-->> 3
      
      







使用する場合、重大なマイナスが1つあります。スレッドに転送されたコードでエラーが発生した場合、そのことはわかりません。このため、このようなコードのデバッグは非常に困難です。プロジェクトの状況を意図的に制御する能力を失わないように、コードの小さなセクションのみを実行スレッドに転送してください。



ユーザーデータを入力



ユーザーデータタイプは、この言語のソースを他の言語、主にC(C)で記述されたソースとリンクするためにLuaで使用されます。 すなわちLuaのCで設計された複雑なユーザー構造がユーザーデータとして受け入れられます。この記事のレベルでは、このタイプは役に立ちませんが、いつでも自分で問題を調べることができます。



おわりに



Lua , Corona SDK , .



All Articles