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

 

* 본 글은 엠바카데로 델파이 제품 담당자 마르코 칸투(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 14387
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 13023
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 15532
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 21064
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 22297
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 17933
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 38228
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 173741
210 델파이 코드 컨버전 빠르게 완료하기 관리자 2019.11.06 595
209 DLL 폼에서 VCL 폼 스타일 적용하기 file 김원경 2019.10.28 5790
208 [고객 사례- 의료, 델파이] 의료용 소프트웨어(폐활량&심전도 체크) - Advanced Spirometer and ECG 관리자 2019.10.25 637
207 데브기어 컴포넌트 컨버터 원리와 구조 설명 험프리 2019.10.11 976
206 [10.3 리오][업데이트 2] 델파이에서 맥OS 64-bit 애플리케이션 개발이 가능합니다. 관리자 2019.07.25 440
205 델파이 코드 주석 추가 및 문서화 방안 험프리 2019.05.30 858
204 [10.3 리오] 리눅스 컴파일러에 non-ARC 메모리 모델이 적용됩니다. 험프리 2018.12.04 381
» [10.3 리오] 델파이 언어의 새로운 변화: 인라인 변수 선언 관리자 2018.11.12 2656
202 [고객사례-게임, 델파이] 오목게임 관리자 2018.10.23 789
201 델파이로 3D 크레딧 스크롤 구현하기(소스제공) file 험프리 2018.05.09 724
200 패키지 개발방식과 DLL개발방식의 차이와 장단점 김원경 2018.05.02 2017
199 RFID 리더(한미IT RF Prisma) 연동하기 - 델파이에서 JAR 이용 [1] 험프리 2017.12.19 1509
198 수원과학대 학생이 델파이로 개발한 '축구 리그 앱' 관리자 2017.11.24 980
197 델파이로 빅데이터 데이터베이스 연동하기(Cassandra, Couchbase, MongoDB) 험프리 2017.10.30 1109
196 [따라하기] 인공지능 오목게임(7) - 오목게임 승자(5돌) 결정 지능프로그램 file 대화마을 2017.10.17 1558
195 [따라하기] 인공지능 오목게임(6) - 흑백 바둑알 놓고 위치저장 file 대화마을 2017.10.01 1050
194 [따라하기] 인공지능 오목게임(5) - 바둑알 놓기 [2] file 대화마을 2017.09.22 955
193 [REST API] 다음 Kakao > 로컬 > 주소검색 연동하기 [2] 험프리 2017.09.18 6275
192 [따라하기] 인공지능 오목게임(4) - 바둑판 그리기 [2] file 대화마을 2017.09.18 2109
191 [따라하기] 인공지능 오목게임(3) - 디자인 구성하기 file 대화마을 2017.09.14 1613