물론입니다! 아래는 번역된 내용입니다:
제목: “이번 주의 팁 #18: Substitute를 활용한 문자열 포맷팅”
원문 게시일: 2012년 10월 4일
업데이트: 2022년 11월 16일
작성자: Titus Winters
빠른 링크: abseil.io/tips/18
코드를 작성하다 보면 종종 템플릿과 몇 개의 런타임 값을 조합해 새로운 문자열을 만들어야 하는 경우가 생깁니다. 예를 들면 Stubby 호출 실패 시 출력할 오류 메시지나, 내부 프로세스에서 전송하는 이메일 본문 등을 작성할 때 이런 상황이 발생합니다. 아마도 sprintf/snprintf
가 google3 밖에서 가장 많이 사용되는 문자열 포맷팅 메커니즘일 것입니다. 하지만 코드베이스를 돌아다니다 보면 사람들이 문자열 포맷팅을 해결하기 위해 너무 많은 시간과 리소스, 코드 라인을 낭비하고 있는 것을 볼 수 있습니다. 이번 팁에서는 몇 가지 일반적인 옵션을 살펴보고 각 접근 방식의 단점을 짚어보겠습니다.
옵션 1: 기본 문자열 연결
일부 개발자는 여전히 기본적인 문자열 연결 방식을 사용합니다:
std::string GetErrorMessage(const std::string& op, const std::string& user,
int id) {
return "Error in " + op + " for user " + user + "(" + std::to_string(id) +
")";
}
하지만 Tip #3에서 언급한 것처럼, 이 접근법에는 몇 가지 문제가 있습니다. operator+()
연산자 체인은 불필요한 임시 객체를 생성하며, 데이터 복사가 반복적으로 발생해 성능 저하를 초래합니다.
옵션 2: absl::StrCat()
[Tip #3]에서 소개된 것처럼, absl::StrCat()
은 불필요한 복사를 피하고 숫자 변환도 처리해줍니다. 또한 string_view
와 함께 작동하므로 C 스타일 문자열을 다룰 때 효율적입니다:
std::string GetErrorMessage(absl::string_view op, absl::string_view user,
int id) {
return absl::StrCat("Error in ", op, " for user ", user, "(", id, ")");
}
하지만 여전히 문자열이 어떤 형태로 출력될지 한눈에 파악하기 어려운 점이 있습니다. 공백이 어디에 있는지, 괄호가 제대로 맞는지 등을 코드만 보고 확인하기 어렵습니다.
옵션 3: absl::Substitute()
하지만 더 나은 옵션이 있습니다: absl::Substitute()
입니다. Substitute()
는 StrCat()
과 동일한 기술을 사용해 숫자 값, std::string
, char*
, 그리고 string_view
를 처리할 수 있습니다. 또한 숫자 타입이나 string_view
를 위해 복잡한 포맷 문자열을 기억할 필요가 없습니다.
대부분의 사람들이 printf 스타일의 포맷 문자열을 이해할 수 있긴 하지만, Substitute
의 포맷 문자열도 충분히 명확합니다:
std::string GetErrorMessage(absl::string_view op, absl::string_view user,
int id) {
return absl::Substitute("Error in $0 for user $1 ($2)", op, user, id);
}
가독성이 좋고 성능도 더 우수합니다. LGTM!