Flutter/Dart

다트 변수, Dart Variable

mayleaf 2021. 8. 28. 00:00

오늘부터 다트 강좌를 시작합니다.

이 강좌를 시작한 이유는 2가지가 있습니다.

  • 첫 번째 이유는 배운 내용을 복습하고 꼼꼼하게 확인하기 위해서입니다. 다른 사람에게 알려주려고 하다 보면 Expert beginner 수준에 있던 지식을 더 끌어올릴 수 있기 때문입니다.
  • 두 번째 이유는 다트 공식 홈페이지에서 다루지 않는 다른 언어들과 비교하고 제가 얻은 경험을 전해서 실전에 도움이 될 수 있는 팁을 드리기 위해서입니다. 

다트

먼저 다트가 어떤 언어인지부터 설명드리겠습니다.

다트는 멀티 플랫폼 런타임을 제공하기 위한 언어입니다. 어떤 환경에서든 편하게 프로그래밍할 수 있고, 누가 만들었는지는 잘 모르겠지만 구글의 다트 팀에서 밀어주고 있는 무료 오픈소스 언어입니다.

 

한때 개발자가 가장 싫어하는 언어 1위에 올랐던 것으로 기억하는데, 요즘은 Flutter 때문에 점점 핫해지고 있는 언어이기도 합니다. 구글 트렌드를 보면 고, 코틀린, 스프링만큼 검색량이 늘어난 것도 확인할 수 있습니다. 그만큼 배울 가치가 늘어난다는 뜻인데요. 개인적으론 플러터만으로도 다트를 할 이유는 충분하다고 생각합니다 :)

 

개발 환경 세팅을 아직 안하신 분은 환경 세팅을 하는 법을 보고 준비해주세요.

변수

아래는 bar라는 문자를 출력하기 위한 코드인데요. 편집기에 잘라서 넣거나 따라 치고 실행해보세요. 프로그래밍은 머슬 메모리, 몸이 반응해서 코드를 짜내는 것도 중요합니다. 그래서 저는 직접 따라 쳐 보는 것을 추천합니다. 따라 치는 건 타자연습이 아니냐라고 말씀하시는 분들도 이해하는 것만큼 익숙해지는 게 중요하다는 건 인정하실 거라고 생각합니다.

※ TIP, IntelliSense(인공지능 기반 추천코드) 를 달아두고 lint(코드 컨벤션, 문법 오류 검사기)를 달아두면 코드 작성을 더 빠르게 할 수 있으며, 실수를 할 확률이 낮아집니다.

void main() {
  String foo = 'bar';
  print(foo);
}

콘솔 창에 지금 bar라고 찍혔을 겁니다. 왜 그런지 이해가 되시나요? 아직까지는 이 코드의 내용을 이해 못 할 수도 있지만 앞으로는 점차 이해하실 겁니다.

 

위 코드 블록에 두 번째 줄을 보면 String foo = 'bar';라는 문장이 있습니다.

String 은 변수의 자료형(데이터 타입), foo는 변수의 이름이며(변수명), 'bar'라는 정보를 가진 객체(스트링 리터럴)에 대해 참조하고 있습니다. 문장의 마지막을 보면 ;(세미콜론)으로 끝나는데, 이 문자는 문장이 끝났다는 것을 컴퓨터에게 알려주는 문자입니다.

 

이제 변수가 뭔지부터 설명드리겠습니다. 먼저 변수란 변할 수 있는 수입니다. 무엇이 변할 수 있냐면 변수에 담긴 값, 정보, 데이터가 변합니다. 이 데이터는 메모리에 저장이 되는데, 메모리는 컴퓨터의 데이터 저장공간입니다. 메모리는 RAM이라고 생각하시면 됩니다. 이 데이터의 형식, 타입을 우리는 데이터 타입이라고 부르고, 한글로 말하면 자료형이라고 부릅니다. 그래서 String foo라고 코드를 적으면 이것은 "String 타입을 가진 변수 foo를 선언할 거야. 메모리에 공간을 준비해." 라고 말하는 것과 같습니다. 그리고 String foo = 'bar'라고 코드를 적으면 "String 타입을 가진 변수 foo를 선언할거야. 메모리에 공간을 준비하고, 그 공간에 'bar'라는 정보를 넣어둬."라고 하는 것이죠.

'bar'라는 정보는 String literal입니다. 변하지 않는 String 타입의 데이터라는 뜻입니다. foo와 bar는 타입이 둘 다 String으로 일치합니다. 변수에 데이터를 할당할 땐 이렇게 타입이 같아야 합니다.

 

이렇게 다트에는 타입이 있음에도 불구하고, 타입을 명시하지 않고 변수를 선언하는 방법도 있는데요. 

바로 var라는 키워드를 이용하는 것입니다. 먼저 예시를 보시죠

void main() {
  var foo = 'bar';
  print(foo);
}

아까 전엔 String foo = 'bar';라는 문장을 사용했는데, 이번엔 String을 var로 대체했습니다.

var는 변수에 할당되는 초기 값을 보고 타입을 추론하겠다는 키워드입니다. foo에 대입되는 정보가 String 이므로 foo의 타입은 String이 되겠죠. 이렇게 적으면 장점이 빠르게 코드를 작성할 수 있고, 초기값에 따라 다트 컴파일러가 타입을 파악하고 String 변수로 인식합니다.

기본 값

다트는 기본값의 개념이 있습니다.

nullable 한 변수의 경우 기본 값이 null입니다. non-nullable 한 변수는 null-safety를 지켜기 위해 해당 변수를 사용하기 전 반드시 null이 아닌 값으로 초기화해줘야 합니다.

 

지역 변수의 경우는 선언될 때 바로 초기화를 해줄 필요는 없지만, 변수가 사용되기 전에는 반드시 값이 할당되어야 합니다. 어떤 언어든 할당되지 않은 참조에 접근하면 문제가 발생합니다.

late 변수

Dart 2.12에서 late 변수가 나왔는데요. late변수를 사용하는 건 두 가지 경우가 있습니다.

  • 첫 번째로 non-nullable 한 변수를 선언할 때, 바로 값을 초기화하지 않고, 나중에 초기화하기 위해서이고
  • 두 번째로 게으른 초기화(lazily initializing)를 위해서입니다.
late String foo;

void main() {
  description = 'foo ang!!!';
  print(description);
}

위 코드를 보면 non-nullable 한 변수인 foo가 초기화 되지 않은 상태로 첫번째 줄에서 선언되어있습니다. 이처러 변수가 사용되기 전에 값이 할당될 것이라고 확신할 수 있을때는 late를 타입 앞에 붙여 non-nullable 한 변수의 초기화가 필요하다는 에러를 수정할 수 있습니다. 우리는 방금 non-nullable한 변수를 선언하고, 나중에 초기화하는 방법에 대해서 봤습니다.

 

그렇다면 초기화를 하지 않고 변수를 사용하면 어떻게 될까요? 변수를 사용하는 시점에서 런타임 에러가 나타납니다. 그러므로 late 변수를 사용할 때에는 사용하기 전에 변수가 초기화됐다는 확신이 있어야 합니다.

 

그런데... 게으른 초기화(lazily initialize)라는 건 뭘까요?

late 변수를 선언과 동시에 초기화를 하는 경우 게으른 초기화를 하게 됩니다.

late String temperature = _readThermometer(); // 이렇게 쓰면 temperature라는 변수가 사용될때 초기화된다!

여러 클래스를 다루다 보면 객체를 생성하는 시점에는 사용하지 않는 변수들이 있습니다.

이런 변수들을 객체 생성시점부터 모두 초기화하면 객체 생성 시간이 느려집니다. 그래서 이렇게 변수를 사용할 때 초기화를 하면 된다! 라며 나온 문법이 바로 게으른 초기화(lazily initialize)입니다.

Final 그리고 const

만약 변수를 절대 변경하지 않으려면 final 아니면 const를 사용하면 됩니다.

final 변수는 한번 변수를 생성하고 초기화 한 이후에는 값을 변경할 수 없습니다.

final name = 'Bob'; // final도 var 처럼 타입추론을 할 수 있습니다!
final String nickname = 'Bobby';

const 변수는 컴파일 타임 상수입니다. 컴파일하는 동안에 값이 정해진다는 뜻입니다. 그래서 인스턴스 변수를 const로 사용하진 못합니다. 또한 const에 할당되는 값은 인스턴스 변수의 값이 아니라 동일하게 const 여야 합니다.

const bar = 1000000; // 기압의 단위
const double atm = 1.01325 * bar; // 표준 기압

변수명 코드 컨벤션, camelCase

double detailKg = 87.3; // 유리수 타입
bool amIMayleaf = false; // 진리값 타입

위 예제를 보면 detailKg이 detailkg 이 아니라 K를 대문자로 표기했습니다. 띄어쓰기를 하지 않는 대신 두 번째 단어부터 단어의 첫 글자를 대문자로 대체해서 읽기 쉽게 만드는 것인데요. 이렇게 표기하는 것을 camelCase라고 합니다. 낙타 등처럼 중간에 문자가 혹처럼 튀어나오기 때문에 camelCase라고 지어졌습니다. 다트의 변수명 코드 컨벤션(대중적으로 따라서 지키는 규약)은 camelCase입니다.

 

그렇다면 변수명은 아무거나 사용 가능할까요? 아닙니다.

변수명 중에서도 사용할 수가 없는 단어들이 있는데요. 이런 단어들은 예약어라고 해서 이미 다트 내부에서 사용하고 있기 때문에 프로그래머가 다트 코드를 짤 때 변수명으로 사용할 수 없습니다. 이런 예약어들은 변수명으로 쓰려고 하면 편집기에서 문법 오류를 지적해주기 때문에 외우실 필요는 없고, 알고만 넘어가시면 될 것 같습니다.

마무리

다트의 기본적인 문법을 다루는 시리즈를 적기 시작했습니다.

좋은 레퍼런스로 사용 될 수 있도록 좋은 글을 쓰기 위해 노력하겠습니다.

글을 읽으시면서 궁금한 내용이나, 하고 싶은 말이 있으시면 댓글을 통해서 말씀해주시면 감사하겠습니다.

'Flutter > Dart' 카테고리의 다른 글

다트 자료형, Dart Built-in Types  (0) 2021.08.29
Dart 기본 예제  (0) 2021.08.27
Dart 개요 번역  (0) 2021.08.26