«Попытка индексировать локально ...» Почему я получаю эту ошибку? - PullRequest
3 голосов
/ 19 мая 2011

Я новичок в Lua и пытаюсь отсортировать вещи в моей голове. Я попробовал этот код:

function newCarousel(images) 
    local slideToImage = function() 
        print("ah!")
    end
end


local testSlide = newCarousel(myImages)
testSlide.slideToImage()

Который дал мне эту ошибку:

Попытка индексировать локальный "testSlide" (нулевое значение) ...

Почему это?

Ответы [ 3 ]

7 голосов
/ 19 мая 2011

Поскольку newCarousel ничего не возвращает, поэтому testSlide равно нулю, поэтому при попытке индексировать его (testSlide.slideToImage точно соответствует testSlide["slideToImage"]) вы получаете ошибку.

Я бы порекомендовал прочитать Программирование на Lua . Возможно, вы сможете определить синтаксис, семантику и идиомы языка методом проб и ошибок, но это займет у вас намного больше времени.

4 голосов
/ 19 мая 2011

Если вы хотите иметь возможность testSlide.slideToImage(), вам нужно изменить newCarousel, чтобы он возвращал таблицу с функцией внутри нее. Простейшая реализация выглядит следующим образом:

function newCarousel(images)
    local t = {}
    t.slideToImage = function() 
        print("ah!")
    end
    return t
end

Вы даже можете построить t и вернуть его за один шаг; следующий код эквивалентен приведенному выше:

function newCarousel(images)
    return {
        slideToImage = function() 
            print("ah!")
        end
    }
end
3 голосов
/ 19 мая 2011

Код, который вы получили сейчас, как указано Mud , ничего не возвращает. (Это не Scheme, Ruby или тому подобное, где последнее выражение является возвращаемым значением.) Кроме того, вы, похоже, думаете, что newCarousel - это объект. Это не так. Это функция. Когда вы закончите звонить newCarousel, все кончено. Он сделал свою работу, что бы это ни было (что в вашем случае создает локальную переменную, которая быстро отбрасывается и возвращает nil).

Правильный код для этого будет выглядеть примерно так:

function newCarousel(images) 
    return function() 
        print("ah!")
    end
end

local testSlide = newCarousel(myImages)
testSlide()

Здесь я теперь newCarousel создаю (анонимную) функцию и немедленно возвращаю ее. Эта анонимная функция связана с testSlide, поэтому я могу вызывать ее в любое время, если захочу, пока testSlide остается в области действия.


Поучительно смотреть на сгенерированный код при игре с Lua. Сначала давайте посмотрим, что luac производит для вашего кода:

main <junk.lua:0,0> (8 instructions, 32 bytes at 0xeb6540)
0+ params, 2 slots, 0 upvalues, 1 local, 3 constants, 1 function
    1   [5] CLOSURE     0 0 ; 0xeb6720
    2   [1] SETGLOBAL   0 -1    ; newCarousel
    3   [7] GETGLOBAL   0 -1    ; newCarousel
    4   [7] GETGLOBAL   1 -2    ; myImages
    5   [7] CALL        0 2 2
    6   [8] GETTABLE    1 0 -3  ; "slideToImage"
    7   [8] CALL        1 1 1
    8   [8] RETURN      0 1

function <junk.lua:1,5> (2 instructions, 8 bytes at 0xeb6720)
1 param, 2 slots, 0 upvalues, 2 locals, 0 constants, 1 function
    1   [4] CLOSURE     1 0 ; 0xeb6980
    2   [5] RETURN      0 1

function <junk.lua:2,4> (4 instructions, 16 bytes at 0xeb6980)
0 params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0 functions
    1   [3] GETGLOBAL   0 -1    ; print
    2   [3] LOADK       1 -2    ; "ah!"
    3   [3] CALL        0 2 1
    4   [4] RETURN      0 1

В вашем коде магистраль создает замыкание, связывает его с именем newCarousel, получает это значение, получает значение myImages и выполняет вызов. Это соответствует local testSlide = newCarousel(myImages). Затем он получает значение slideToImage из локальной таблицы (testSlide). Проблема в том, что testSlide - это не таблица, а nil. Вот откуда приходит ваше сообщение об ошибке. Заметьте, это не единственная ошибка, но это первая ошибка, которую видит среда выполнения и которая заставляет все задыхаться. Если вы вернули реальную функцию из newCarousel, вы получите другую ошибку. Например, если бы я добавил строку return slideToImage в функцию newCarousel, сообщение об ошибке было бы «попытка индексировать локальный« testSlide »(значение функции)».

...