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

 

* 본 글은 엠바카데로 델파이 제품 담당자 마르코 칸투(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 15438
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 13961
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 16499
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 22055
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 23268
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 18923
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 39255
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 174699
1342 [DelphiCon 요약] 델파이로 웹 다루기 (Powering the Web with Delphi) file 관리자 2021.02.16 1120
1341 [고객 사례- POS, C++빌더] YG-POS - 소상공인을 위한 무료 소프트웨어 관리자 2021.02.08 649
1340 [고객 사례- 금융, 델파이] 주식, 화폐 등 금융 정보 분석 소프트웨어 - 게임스탑, 비트코인, 아마존, 구글 등 관리자 2021.02.04 627
1339 ‘장기 활용 가능성’이 가장 뛰어난 프레임워크는? (델파이 VS. WPF VS. ELECTRON) 관리자 2021.02.01 462
1338 [델파이 웹개발] 델파이로 풀스택 웹 개발하기 - uniGUI 활용 (Full Stack Web Development with uniGUI for Delphi) file 관리자 2021.02.01 4290
1337 버전별 업데이트된 주요 기능들 (C++빌더6 / 델파이7부터 최신 버전까지!) 관리자 2021.01.29 376
1336 이 달의 기술자료 - 2021년 02월 file 험프리 2021.01.26 510
1335 [샘플 프로젝트] 심박 측정기-델파이/C++빌더와 IOT 연동하기 관리자 2021.01.25 459
1334 C++ 유니코드 문자열 리터럴(Unicode String Literal) 활용 방법 관리자 2021.01.22 449
1333 C++빌더 마이그레이션, C++ 프로젝트를 간편하게 업데이트 하는 방법 관리자 2021.01.19 310
1332 [고객 사례- 델파이, 게임] 체스 오프닝 위저드 - 60,000여명의 체스 플레이어가 실제로 사용하는 앱 관리자 2021.01.18 713
1331 생산성을 끌어올려줄 겟잇(GetIt)의 최신 컴포넌트들 관리자 2021.01.18 513
1330 [DelphiCon 요약] High DPI 고해상도를 VCL에서 활용하기 (Leveraging High DPI in VCL Applications) 관리자 2021.01.13 767
1329 [DelphiCon 요약] Spring4D 소개 - 델파이 개발을 한수준 높이기 (Introduction to Spring4D - Taking Delphi Development to the Next Level) 관리자 2021.01.08 1146
1328 새해 목표: LEARN, TEACH, REPEAT. 관리자 2021.01.05 315
1327 [DelphiCon 요약] 델파이로 함수형 프로그래밍하기 (Functional Programming With Delphi) 관리자 2020.12.29 710
1326 [DelphiCon 요약] 델파이 고성능 구현 (High Performance Delphi) 관리자 2020.12.27 900
1325 [TOP 10] 2020년 하반기, 개발자가 사랑한 기술자료는? 관리자 2020.12.24 353
1324 이 달의 기술자료 - 2021년 01월 file 험프리 2020.12.24 412