객체 더하기
Coddy Lua 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 70개 중 26번째.
이미 __tostring 및 __eq와 같은 메타메소드를 통해 객체의 동작을 사용자 정의하는 방법을 살펴보았습니다. 이제 덧셈을 시작으로 이를 산술 연산까지 확장해 보겠습니다.
__add 메타메소드는 두 객체 사이에서 + 연산자를 사용할 때 어떤 일이 일어나는지를 정의합니다. Lua가 a + b를 발견하면, 두 피연산자 중 하나의 메타테이블에서 __add를 찾습니다.
local Vector = {}
Vector.__index = Vector
function Vector:new(x, y)
local obj = {x = x, y = y}
setmetatable(obj, Vector)
return obj
end
function Vector.__add(v1, v2)
return Vector:new(v1.x + v2.x, v1.y + v2.y)
end__add는 콜론이 아닌 마침표(점)로 정의된다는 점에 유의하세요. 이 함수는 두 피연산자를 인자로 받으며, 원본 중 어느 것도 수정하지 않고 새로운 객체를 반환해야 합니다. 이렇게 하면 연산을 예측 가능하고 안전하게 유지할 수 있습니다.
local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b
print(c.x, c.y) -- 출력: 4 6핵심적인 통찰은 __add가 객체 내부뿐만 아니라 메타테이블 자체(여기서는 Vector)에 있어야 한다는 것입니다. 모든 인스턴스에 대해 Vector를 메타테이블로 설정했으므로, 이들은 모두 이 동작을 자동으로 공유합니다.
챌린지
쉬움+ 연산자를 사용하여 덧셈을 지원하는 Vector 클래스를 만들어 봅시다. 이것은 연산자 오버로딩(operator overloading)의 첫 번째 단계로, 여러분이 만든 객체가 Lua의 내장 연산자와 자연스럽게 작동하도록 만드는 과정입니다.
코드는 두 개의 파일로 구성됩니다:
Vector.lua:x와y컴포넌트를 가진 Vector 클래스를 정의합니다.:new(x, y)생성자를 포함하고, 두 벡터를 더했을 때 컴포넌트가 합쳐진 새로운 벡터가 생성되도록__add메타메소드를 구현하세요.__add는 콜론(colon)이 아닌 점(dot) 구문을 사용하며 두 피연산자를 인자로 받는다는 점을 기억하세요.main.lua: Vector 모듈을 불러오고(require), 벡터 인스턴스를 생성한 뒤, 이들을 더했을 때 올바른 결과가 나오는지 확인합니다.
네 개의 입력을 받게 됩니다:
- 첫 번째 벡터의 x 컴포넌트
- 첫 번째 벡터의 y 컴포넌트
- 두 번째 벡터의 x 컴포넌트
- 두 번째 벡터의 y 컴포넌트
메인 파일에서 주어진 컴포넌트로 두 개의 벡터를 생성하고, + 연산자를 사용하여 더한 뒤, 결과 벡터의 x와 y 값을 각각 별도의 줄에 출력하세요.
예를 들어, 입력값이 3, 4, 1, 2라면 출력은 다음과 같아야 합니다:
4
6첫 번째 벡터 (3, 4)와 두 번째 벡터 (1, 2)를 더하면 새로운 벡터 (4, 6)이 됩니다.
치트 시트
__add 메타메소드는 두 객체 사이에 + 연산자를 사용할 때 어떤 일이 일어날지 정의합니다.
Lua가 a + b를 발견하면, 두 피연산자 중 하나의 메타테이블에서 __add를 찾습니다.
local Vector = {}
Vector.__index = Vector
function Vector:new(x, y)
local obj = {x = x, y = y}
setmetatable(obj, Vector)
return obj
end
function Vector.__add(v1, v2)
return Vector:new(v1.x + v2.x, v1.y + v2.y)
end__add는 콜론이 아닌 마침표(dot)로 정의됩니다. 이 메소드는 두 피연산자를 인자로 받으며, 원본을 수정하는 대신 새로운 객체를 반환해야 합니다.
local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b
print(c.x, c.y) -- 출력: 4 6__add는 객체 내부가 아니라 메타테이블 자체에 있어야 합니다.
직접 해보기
-- Vector 모듈 가져오기
local Vector = require('Vector')
-- 입력 읽기
local x1 = tonumber(io.read())
local y1 = tonumber(io.read())
local x2 = tonumber(io.read())
local y2 = tonumber(io.read())
-- TODO: 입력값을 사용하여 두 개의 Vector 인스턴스 생성
-- TODO: + 연산자를 사용하여 두 벡터 더하기
-- TODO: 결과 벡터의 x와 y 값을 별도의 줄에 출력
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.