루아에서 `table.copy`는 어떻게 구현하나요?
_____A: Lua에는 표준 라이브러리에 `table.copy` 함수가 내장되어 있지 않습니다. 따라서 테이블을 복사하려면 직접 함수를 작성해야 합니다. 복사 방식에는 얕은 복사(shallow copy)와 깊은 복사(deep copy)가 있습니다.
---
1. 얕은 복사(Shallow Copy) 구현법
얕은 복사는 가장 바깥쪽 테이블만 새로 만들고, 그 안의 값들은 원본과 동일한 참조를 가집니다.
```lua
function shallow_copy(orig)
local copy = {}
for k, v in pairs(orig) do
copy[k] = v
end
return copy
end
```
- 장점: 간단하고 빠름
- 단점: 중첩된 테이블이 있을 경우 원본과 복사본이 같은 테이블을 참조함
---
2. 깊은 복사(Deep Copy) 구현법
깊은 복사는 테이블 안에 또 테이블이 있을 경우 그 내부까지 모두 재귀적으로 복사합니다.
```lua
function deep_copy(orig, copies)
copies = copies or {}
if type(orig) ~= "table" then
return orig
elseif copies[orig] then
return copies[orig]
end
local copy = {}
copies[orig] = copy
for k, v in pairs(orig) do
copy[deep_copy(k, copies)] = deep_copy(v, copies)
end
setmetatable(copy, deep_copy(getmetatable(orig), copies))
return copy
```
- `copies` 테이블은 재귀 호출 시 이미 복사한 테이블을 저장하여 순환 참조로 인한 무한 재귀를 방지합니다.
- 메타테이블도 함께 복사하여 기능적 동일성을 유지할 수 있습니다.
---
3. 사용 예제
```lua
local original = {
a = 1,
b = {2, 3},
c = {x = 4}
}
local shallow = shallow_copy(original)
local deep = deep_copy(original)
-- 수정 전
print(original.b[1]) --> 2
print(shallow.b[1]) --> 2
print(deep.b[1]) --> 2
-- shallow 복사본의 내부 테이블 수정 (원본에도 영향)
shallow.b[1] = 10
print(original.b[1]) --> 10
-- deep 복사본의 내부 테이블 수정 (원본에는 영향 없음)
deep.b[1] = 20
print(original.b[1]) --> 10
```
---
요약
- Lua에서 `table.copy`는 기본 제공되지 않음
- 간단한 경우 `shallow_copy`를 사용
- 중첩된 테이블까지 안전하게 복사하려면 `deep_copy` 구현 필요
- 깊은 복사 시 순환 참조 주의, 위의 예제 함수는 이를 처리함
---
이상으로 Lua에서 `table.copy` 구현에 관한 FAQ 답변입니다.
기본적으로, 루아의 테이블은 참조 타입이기 때문에, 단순히 테이블을 할당하면 원본 테이블의 참조만 복사됩니다.
따라서 원본 테이블을 수정하면 복사된 테이블에도 영향을 미치게 됩니다.
이를 방지하기 위해서는 테이블의 내용을 복사해야 합니다.
아래는 루아에서 `table.copy` 함수를 구현하는 방법에 대한 예시입니다.
이 예시는 얕은 복사와 깊은 복사를 모두 지원하는 방법을 보여줍니다.
얕은 복사 (Shallow Copy) 얕은 복사는 테이블의 최상위 레벨의 키와 값을 복사합니다.
즉, 중첩된 테이블은 복사되지 않고 원본 테이블의 참조가 유지됩니다.
```lua function table.copy(source) local copy = {} for k, v in pairs(source) do copy[k] = v end return copy end ``` 깊은 복사 (Deep Copy) 깊은 복사는 테이블의 모든 레벨을 재귀적으로 복사합니다.
이 방법은 중첩된 테이블도 새로운 테이블로 복사하여 원본 테이블과의 참조를 끊습니다.
```lua function table.deepCopy(source) if type(source) ~= "table" then return source -- 테이블이 아닌 경우 그대로 반환 end local copy = {} for k, v in pairs(source) do copy[table.deepCopy(k)] = table.deepCopy(v) -- 키와 값을 재귀적으로 복사 end return copy end ``` 사용 예시 이제 위에서 정의한 `table.copy`와 `table.deepCopy` 함수를 사용하여 테이블을 복사해 보겠습니다.
```lua local original = { a = 1, b = { x = 10, y = 20 }, c = 3 } local shallowCopy = table.copy(original) local deepCopy = table.deepCopy(original) -- 원본 테이블 수정 original.b.x = 100 print(original.b.x) -- 100 print(shallowCopy.b.x) -- 100 (얕은 복사이므로 원본과 참조 공유) print(deepCopy.b.x) -- 10 (깊은 복사이므로 독립적) ``` 주의사항 1. 순환 참조 : 깊은 복사를 구현할 때, 순환 참조가 있는 테이블을 복사하려고 하면 무한 루프에 빠질 수 있습니다.
이를 방지하기 위해, 이미 복사된 테이블을 추적하는 방법을 사용할 수 있습니다.
2. 메타테이블 : 메타테이블이 있는 테이블을 복사할 때, 메타테이블도 복사해야 할 필요가 있습니다.
이 경우, 메타테이블을 따로 처리하는 로직을 추가해야 합니다.
3. 성능 : 깊은 복사는 성능에 영향을 미칠 수 있습니다.
복사할 테이블의 크기와 깊이에 따라 성능이 저하될 수 있으므로, 필요한 경우에만 깊은 복사를 사용하는 것이 좋습니다.
이와 같이 루아에서 테이블을 복사하는 방법을 이해하고 구현하면, 다양한 상황에서 유용하게 활용할 수 있습니다.
작성자:
김도영 [비회원]
| 작성일자: 1년 전
2024-12-05 19:51:54
조회수: 159 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
조회수: 159 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.