델파이 언어의 새로운 변화: 인라인 변수 선언

 

* 본 글은 엠바카데로 델파이 제품 담당자 마르코 칸투(Marco Cantu)의 글을 일부 발췌 및 번역한 글입니다.

전문은 다음 링크를 통해 확인할 수 있습니다: http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html

 

 

델파이 언어가 10.3 버전부터 로컬 변수 선언에 있어 훨씬 더 융통적으로 변합니다. 매우 핵심적인 기능 변화라고 볼 수 있습니다. 이번 업데이트는 본래 파스칼(Pascal) 언어의 핵심 개념을 깨는 변화이기는 합니다. 하지만 이 변화는 많은 장점을 제공하며, 이를 통해 불필요한 코드를 줄일 수 있습니다.

 

 

예전 스타일의 Var 블록

 

터보파스칼 1부터 지금까지 기존 파스칼 언어 규칙에 따라 모든 로컬 변수 선언은 함수(function), 프로시저(procedure), 메소드(method) 작성 전에 var 블록에 선언해야만 했습니다.

 

procedure Test;
var
  I: Integer;
begin
  I := 22;
  ShowMessage (I.ToString);
end;

 

 

인라인 변수 선언

 

새로운 인라인 변수 선언 구문을 사용해 코드 블록에서 바로 변수를 선언할 수 있습니다 (여러 기호 허용):

 

 

procedure Test;
begin
  var I, J: Integer;
  I := 22;
  j := I + 20;
  ShowMessage (J.ToString);
end;

 

작은 차이로 보일 수도 있지만, 이번 변화를 통해 많은 효과를 얻을 수 있습니다.

어떤 효과를 얻을 수 있을지 아래를 통해 확인해보세요.

 

 

인라인 변수 초기화

 

이전 선언 방식과 비교해 가장 크게 변한 점은 변수 인라인 선언과 초기화를 한 문장에서 끝낼 수 있다는 것입니다.

함수 선언부에서 변수를 초기화 하는 것도 훨씬 더 보기에 쉽고 파악하기 좋습니다.

 

procedure Test; // declaration and initialization in a single statement
begin
  var I: Integer := 22;
  ShowMessage (I.ToString);
end;

 

또한 코드 블록에서만 변수를 사용하게 되면, 초기값 (0 또는 nil)을 설정하고 난 뒤에 실제 값을 할당하는 것보다

효율적입니다. 변수 선언을 적절한 초기값 지정 시점에 할 수 있기 때문입니다.

 

다시 말해, 이전에는 전체 코드 블록에 걸쳐 모든 로컬 변수들을 확인했다면, 이제는 변수 선언 위치에서만 그리고 코드 블록의 마지막 부분까지만 확인하면 됩니다.

 

procedure Test1; // multiple inline declarations (symbols declared when used)
begin
  var I: Integer := 22;
  var J: Integer := 22 + I;
  var K: Integer := I + J;
  ShowMessage (K.ToString);
end;

 

 

중첩된 블록에 선언된 인라인 변수의 범위와 수명

 

범위 제한은 전체 프로시저, 메소드가 아닌, begin-end 코드 블록에만 인라인 변수가 표시되기 때문에 더 의미가 있습니다. 인라인 변수 선언은 선언한 블록으로 범위가 제한되며 블록 외에서는 사용할 수 없습니다. 선언한 변수의 수명 또한 블록 안에서만 적용되는 것으로 제한됩니다. 관리 데이터 유형(인터페이스, 스트링, 관리 레코드 등)은 지금까지와 같이 프로시저나 메소드 끝 부분이 아닌 하위 블록의 마지막 부분에서 처리될 것입니다.

 

procedure Test2; // scope limited to local block
begin
  var I: Integer := 22;
  if I > 10 then
  begin
    var J: Integer := 3;
    ShowMessage (J.ToString);
  end
  else
  begin
    var K: Integer := 3;
    ShowMessage (J.ToString); // COMPILER ERROR: "Undeclared identifier: J"
  end;
  // J and K not accessible here
end;

 

위 마지막 코드에서 확인할 수 있듯, begin-end 블록에 선언된 변수는 특정 블록에만 표시되며 그 블록이 종료된 이후에는 적용되지 않습니다. if 문 끝에 위치한 J와 K 값은 이후에는 확인할 수 없는 것입니다.

앞서 설명했듯, 이와 같은 효과는 단순히 가시성 문제에만 국한되는 것은 아닙니다. 인터페이스 참조나 레코드와 같이 변수 또한 블록 마지막 부분에서 정리되는 것입니다.

 

procedure Test99;
begin

  // some code

  if (something) then
  begin
    var Intf: IInterface = GetInterface; // Intf.AddRef
    var MRec: TManagedRecord = GetMRecValue; // MRec.Create + MRec.Assign
    UseIntf(Intf);
    UseMRec(MRec);
  end; // Intf.Release and MRec.Destroy are implicitly called at end of scope

  // more code

end; // no additional cleanup

 

인라인 변수에 대한 타입 유추

인라인 변수의 또 다른 큰 이점은 컴파일러가 여러 상황에서 할당된 식 또는 값의 유형을 파악해 인라인 변수의 타입을 유추할 수 있다는 것입니다.

 

procedure Test;
begin
  var I := 22;
  ShowMessage (I.ToString);
end;

 

r-value 표현식(":=" 다음에 오는 값)을 분석해 변수의 타입을 판별합니다. 위의 경우와 같이 숫자 값 22(ShortInt)가 Integer로 확장되는 경우와 같이 일부 데이터 유형은 더 큰 유형으로 "확장"됩니다. 일반적으로 우항의 수식 유형이 정수형이고 32비트보다 작으면 변수는 정수로 선언됩니다. 특정한 작은 숫자 유형을 사용하려면 명시적으로 유형을 지정해 사용할 수 있습니다.

 

이 기능은 정수 또는 문자열에 대한 일부 키입력을 줄일 수 있지만, 저너릭(Generic)의 인스턴스처럼 복잡한 유형의 경우 변수 타입 유추하는 것이 상당히 유용합니다.

아래 코드를 보면, MyDictionary 변수에 대한 TDirtionary 타입 유추와 APair 변수에 대한 TPair 타입 유추를 확인할 수 있습니다.

procedure NewTest;
begin
  var MyDictionary := TDictionary<string, Integer>.Create;
  MyDictionary.Add ('one', 1);
  var APair := MyDictionary.ExtractPair('one');
  ShowMessage (APair.Value.ToString)
end;

 

인라인 상수

변수와 같이, 상수도 인라인으로 선언할 수 있습니다. 타입 지정 함수 또는 타입 미지정 함수 모두에 적용할 수 있습니다.

 

  const M: Integer = (L + H) div 2; // single identifier, with type specifier
  const M = (L + H) div 2; // single identifier, without type specifier

 

For 루프에서 인라인 루프 변수 선언 사용

인라인 변수 선언을 활용할 수 있는 또다른 상황은 for-to 루프와 for-in 루프를 포함한 for 루프 문입니다.

 

  for var I: Integer := 1 to 10 do ...
  for var Item: TItemType in Collection do...

 

형식 유추를 활용해 코드를 더 단순화 가능합니다.

 

  for var I := 1 to 10 do ...
  for var Item in Collection do ...

 

아래 예제 코드와 같이 제한된 범위의 인라인 변수를 사용하면 더욱 유용합니다. 루프 외부에서 I 변수를 사용하면 컴파일러 오류가 발생합니다.(대부분 경우 경고가 발생합니다.)

 

procedure ForTest;
begin
  var total := 0;
  for var I: Integer := 1 to 10 do
    Inc (Total, I);
  ShowMessage (total.ToString);
  ShowMessage (I.ToString); // compiler error: Undeclared Identifier ‘I’
end;

 

 

인라인 선언에 대한 정리

 

인라인 변수 선언은 타입 추론과 지역 범위(local scope)와 더불어 델파이 언어에 신선한 변화를 줄 것입니다. 파스칼 소스 코드의 가독성은 보존해야 할 핵심 원칙으로 남아있지만, 핵심 수준에서 언어를 최신식으로 현대화하기 위한 중요한 변화입니다. 인라인 변수는 전통적인 코딩 스타일과는 다른 다양한 이점들이 있습니다. 

 

여전히 소스 코드를 그대로 유지하고 동료 개발자들에게 전통 선언 방식을 고수하는 것이 문제가 되지는 않지만: 기존 코드나 작성 방식이 잘못되었다는 것은 절대 아닙니다, 인라인 변수 선언은 분명히 새로운 기회가 될 것입니다. 그냥 단지.. 저의 경우에는 델파이의 오래전 버전으로 돌아가기에는 이미 어렵다는 말만 전하고 싶습니다.

 

 

관련글


 

 

10.3 리오의 업데이트 버전들

 

번호 제목 글쓴이 날짜 조회 수
공지 [DelphiCon 요약] 코드사이트 로깅 실전 활용 기법 (Real-world CodeSite Logging Techniques) 관리자 2021.01.19 15454
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 13966
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 16503
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 22059
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 23268
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 18925
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 39261
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 174727
250 델파이 XE2의 Namespace 문제 박병일 2012.01.19 8692
249 [델파이 문법] 프로시저와 함수 #1 file 관리자 2012.07.23 8663
248 [링크]안드로이드를 위한 데이터 스냅 서버 박병일 2012.01.12 8428
247 [델파이 문법] 데이터 타입, 변수 및 상수 #2 file 관리자 2013.02.04 8238
246 [델파이 문법] 프로그램과 유닛 #2 file 관리자 2012.09.06 8222
245 [델파이 문법] 클래스와 객체 #13 file 관리자 2012.06.11 8032
244 [델파이 문법 시리즈] #1. 익명메소드 - 문법 file 관리자 2012.04.04 8005
243 dbExpress 에는 TUpdateSQL 컴포넌트가 없어요! file 박병일 2012.03.05 7955
242 VCL Style을 사용하면서 Edit 콘트롤의 컬러 변경하기 file 박병일 2012.02.08 7948
241 [델파이 문법 시리즈] #8. 제네릭 - 문법 변경 사항(마지막) file 관리자 2012.04.03 7871
240 Runtime Packages 옵션으로 프로그램(배포) 용량 줄이기 [4] file Humphery 2013.12.19 7767
239 2012년 소프트웨어 트랜드 세미나 박병일 2012.01.12 7612
238 [델파이 문법] 문법 요소 #1 file 관리자 2012.09.17 7593
237 [델파이 문법] 문법 요소 #11 file 관리자 2012.11.12 7577
236 [델파이 문법] 클래스와 객체 #2 [1] file 관리자 2012.04.17 7492
235 [델파이 문법] 문법 요소 #10 file 관리자 2012.11.08 7451
234 [델파이 문법] 문법 요소 #12 file 관리자 2012.11.15 7434
233 [델파이 문법] 프로그램과 유닛 #3 file 관리자 2012.09.10 7433
232 [델파이 문법 시리즈] #4. 익명메소드 - 활용법(마지막) file 관리자 2012.04.10 7421
231 [델파이 문법] 클래스와 객체 #6 file 관리자 2012.04.25 7419