객체 연결하기
Coddy Lua 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 70개 중 28번째.
Lua의 .. 연산자는 문자열을 연결하지만, 객체를 문자열과 결합하고 싶다면 어떻게 해야 할까요? __concat 메타메소드를 사용하면 이것이 어떻게 작동해야 하는지 정확하게 정의할 수 있습니다.
Lua가 a .. b를 만나고 한 피연산자에 __concat 메타메서드가 있으면, 두 값을 인자로 하여 해당 함수를 호출합니다. 이는 객체가 문자열 표현식에 자연스럽게 어우러지도록 하고 싶을 때 유용합니다.
local Name = {}
Name.__index = Name
function Name:new(first, last)
local obj = {first = first, last = last}
setmetatable(obj, Name)
return obj
end
function Name.__concat(a, b)
if type(a) == "string" then
return a .. b.first .. " " .. b.last
else
return a.first .. " " .. a.last .. b
end
end함수가 어떤 피연산자가 문자열인지 확인하는 점에 유의하세요. ..은 "Hello " .. obj 또는 obj .. "!"와 같이 사용될 수 있으므로, 메타메소드는 두 경우를 모두 처리해야 합니다.
local person = Name:new("Ada", "Lovelace")
print("Dr. " .. person) -- 출력: Dr. Ada Lovelace
print(person .. " PhD") -- 출력: Ada Lovelace PhD다른 연산자 메타메서드와 마찬가지로, __concat은 점 구문을 사용하며 두 피연산자를 인자로 받습니다. 산술 메타메서드와의 주요 차이점은 일반적으로 객체와 문자열이라는 혼합된 타입을 다루게 된다는 점입니다.
챌린지
쉬움.. 연산자를 사용하여 문자열 표현식에 자연스럽게 녹아들 수 있는 Title 클래스를 만들어 보겠습니다. 이는 경칭이나 접미사를 사람의 직함에 추가하는 것과 같이, 객체를 문자열과 읽기 쉽고 직관적인 방식으로 결합하고 싶을 때 유용합니다.
코드는 두 개의 파일로 구성됩니다:
Title.lua: 타이틀 문자열을 저장하는text필드를 가진 Title 클래스를 정의합니다.:new(text)생성자를 포함하고__concat메타메소드를 구현하세요. 메타메소드는 객체 앞에 문자열이 오는 경우("prefix" .. obj)와 객체 뒤에 문자열이 오는 경우(obj .. "suffix")의 두 가지 케이스를 모두 처리해야 합니다. 결과는 문자열과 타이틀의 텍스트를 적절하게 결합해야 합니다.main.lua: Title 모듈을 불러오고(require), 타이틀 인스턴스를 생성한 다음, 양방향에서의 연결(concatenation)을 보여줍니다.
세 개의 입력을 받게 됩니다:
- 타이틀 텍스트 (예: "Engineer")
- 타이틀 앞에 붙일 접두사 문자열 (예: "Senior ")
- 타이틀 뒤에 붙일 접미사 문자열 (예: " III")
메인 파일에서 주어진 텍스트로 Title을 생성하세요. 그런 다음 두 번의 연결을 수행하고 각 결과를 별도의 줄에 출력하세요:
- 접두사 문자열과 타이틀 객체를 연결합니다.
- 타이틀 객체와 접미사 문자열을 연결합니다.
예를 들어, 입력값이 Engineer, Senior , III인 경우 출력은 다음과 같아야 합니다:
Senior Engineer
Engineer III첫 번째 줄은 접두사와 타이틀이 결합된 것을 보여주고, 두 번째 줄은 타이틀과 접미사가 결합된 것을 보여줍니다. 여러분이 만든 __concat 메타메소드가 이러한 자연스러운 문자열 결합을 가능하게 합니다!
치트 시트
__concat 메타메소드를 사용하면 객체로 작업할 때 .. 연결 연산자에 대한 사용자 정의 동작을 정의할 수 있습니다.
Lua가 a .. b를 만나고 한 피연산자에 __concat 메타메소드가 있으면, 두 값을 인자로 하여 해당 함수를 호출합니다.
기본 구현
local MyClass = {}
MyClass.__index = MyClass
function MyClass:new(value)
local obj = {value = value}
setmetatable(obj, MyClass)
return obj
end
function MyClass.__concat(a, b)
if type(a) == "string" then
return a .. b.value
else
return a.value .. b
end
end양쪽 피연산자 순서 처리
..는 "string" .. obj 또는 obj .. "string"과 같이 사용될 수 있으므로, 메타메소드는 어떤 피연산자가 문자열인지 확인하고 두 경우를 모두 처리해야 합니다:
function Name.__concat(a, b)
if type(a) == "string" then
return a .. b.first .. " " .. b.last
else
return a.first .. " " .. a.last .. b
end
end사용 예시
local person = Name:new("Ada", "Lovelace")
print("Dr. " .. person) -- 출력: Dr. Ada Lovelace
print(person .. " PhD") -- 출력: Ada Lovelace PhD다른 연산자 메타메소드와 마찬가지로, __concat은 점(dot) 구문을 사용하며 두 피연산자를 인자로 받습니다.
직접 해보기
-- 입력 읽기
local titleText = io.read()
local prefix = io.read()
local suffix = io.read()
-- Title 모듈 불러오기
local Title = require('Title')
-- TODO: 주어진 titleText로 Title 인스턴스 생성
-- TODO: prefix를 title 객체와 연결하고 결과 출력
-- TODO: title 객체를 suffix와 연결하고 결과 출력
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.