Lua: Почему изменение значения одной переменной меняет значение и другой? - PullRequest
1 голос
/ 21 декабря 2010

Я думаю, что запустив этот код, вы получите именно то, что я имею в виду.Я хочу зарегистрировать 5 имен в реестре ( человек ).Я зацикливаюсь 5 раз, и в каждом цикле у меня есть переменная newPerson , которая должна сохранять всю информацию о человеке и затем добавляться в регистр people .В этом примере для упрощения регистрируются только имена людей.Проблема в том, что в итоге все люди обращаются к одному и тому же имени: «Петра».Я немного поиграл с этим, но не могу найти разумную причину такого поведения.Помощь оценена!

local people={}
local person={
    name="Johan",
    lastName="Seferidis",
    class="B"
}
local names={"Markus", "Eva", "Nikol", "Adam", "Petra"} --people to register


for i=1, 5 do --register 5 people
    local newPerson=person
    local name=names[i]
    for field=1, 3 do --for each field(name, lastname, class)
        if field==1 then newPerson["name"]=name end --register name
    end
    people[i]=newPerson
end

print("First person name: " ..people[1]["name"])
print("Second person name: "..people[2]["name"])
print("Third person name: " ..people[3]["name"])

Ответы [ 3 ]

5 голосов
/ 21 декабря 2010

Здесь важно то, что переменные, «содержащие» таблицу, на самом деле содержат только ссылку на таблицу.Копирование переменных, содержащих таблицы, только копирует ссылку в эту таблицу и, таким образом, представляет ту же таблицу, что и в этом примере:

a={"x","y","z"}
b=a
b[2]="Q"
print(a[2]) -- returns Q and not y. Why is easily seen by doing:
print(a,b) -- returns table: 0xXXXXXX 0xXXXXXX indicating it's the same table

Если вы действительно хотите получить копию таблицы, выВам нужно будет прибегнуть к чему-то вроде http://lua -users.org / wiki / CopyTable

2 голосов
/ 21 декабря 2010

Попробуйте это:

local people={}
local names={"Markus", "Eva", "Nikol", "Adam", "Petra"} --people to register

for i=1, 5 do
    people[i]={
        name=names[i],
        lastName="Seferidis",
        class="B"
        }
end
1 голос
/ 21 декабря 2010

Похоже, вы пытаетесь использовать person в качестве прототипа объекта .Вот некоторые изменения в коде, который добавляет функцию new для упрощения прототипирования объектов.

object = {}
function object:new(o)
    -- use the table provided, or create a new table
    o = o or {}
    -- use this object as a prototype
    setmetatable(o, self)
    self.__index = self
    return o
end

local people={}
local person=object:new({name="Johan",lastName="Seferidis",class="B"})

local names={"Markus", "Eva", "Nikol", "Adam", "Petra"} --people to register

for i=1, 5 do --register 5 people
    local newPerson=person:new({["name"]=names[i]})
    people[i]=newPerson
end

print("First person name: " ..people[1].name.." "..people[1].lastName.." "..people[1].class)
-->First person name: Markus Seferidis B

print("Second person name: "..people[2].name.." "..people[2].lastName.." "..people[2].class)
-->Second person name: Eva Seferidis B

print("Third person name: " ..people[3].name.." "..people[3].lastName.." "..people[3].class)
-->Third person name: Nikol Seferidis B
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...