지난 게시글에서 Flutter 개발 환경 구축도 완료했겠다, 이제는 Dart
를 익혀보려고 한다. 언어를 배울 때 빠지면 섭한 Hello, World!
를 VS Code에서 출력해보았다.
구문은 간단하다.
void main() { print('hello, world!'); }
main 함수는 Dart 프로그램의 Entry point
이기 때문에 class
, type
을 제외한 코드는 반드시 main 함수에 작성되어야 한다. VS Code에서는 친절하게도 main()
이 없으면 코드 실행이 불가하게 Run
을 없애버린다.
그리고 javascript
, typescript
와 같은 다른 프로그래밍 언어에서는 auto formatter
가 자동으로 ;(세미콜론)
을 달아주는데 Dart는 그런 기능을 지원해주지 않으니 반드시 셀프로 세미콜론을 달아줘야 한다.
Dart로 개발을 할 때 이 정도만 유의하면 되니 본격적으로 변수에 대해서 알아보도록 하겠다.
void main() { var name = '지지'; }
Dart 컴파일러는 String name = '지지'
와 같이 변수 앞에 타입을 명시적으로 지정하지 않아도 알기 때문에 var
를 사용해도 된다.
다만 Dart 스타일 가이드의 권장 방식대로 함수
나 메소드
내부에 지역 변수
를 선언할 때는 var
를 사용하고, class
에서 변수
나 property
를 선언할 때는 type
을 지정해주는 것이 좋다.
void main() { var name; // 변수의 값을 지정하지 않거나 dynamic dyname; // 변수 타입을 명시적으로 지정하거나(dynamic) if(dyname is String){ // dyname에 String 관련 option을 사용할 수 있다. }; if(dyname is int){ // dyname에 int 관련 option을 사용할 수 있다. }; }
dynamic type
은 변수에 들어올 데이터의 타입이 불확실할 때 사용할 수 있다. json
과 같이 동적인 데이터를 처리할 때 유용할 수 있으나, 컴파일러가 타입을 확인하지 않아 발생할 수 있는 오류를 미연에 방지할 수 없다는 점과 코드의 가독성 저하 문제로 인해 반드시 필요할 때만 사용하는 것이 좋다.
변수의 값을 지정하지 않고 var
를 사용해도 dynamic type
과 동일하게 다양한 타입의 데이터를 받을 수 있으나, 한 번 선언된 데이터의 타입을 유지해야 한다는 면에서 dynamic type의 변수와 차이점이 있다.
dynamic type
의 경우 데이터의 타입을 유지하지 않아도 오류가 발생하지 않는다.
void main() { String? gigi = 'gigi'; gigi = null; if(gigi != null){ gigi.isNotEmpty; }; //또는 null값을 체크하는 if문을 다음과 같이 축약하여 사용할 수 있다. gigi?.isNotEmpty; }
런타임 시에 null 값을 참조하여 발생할 수 있는 오류를 미연에 방지하기 위해 nullable 변수
를 사용할 수 있다. nullable 여부
를 지정하는 방법은 간단하게 변수 타입 뒤에 ?
를 붙이기만 하면 된다. 이제 null 여부
를 확인한 뒤 변수 타입에 맞는 옵션을 사용하면 되고, 이렇게 nullable 변수를 사용함으로써 런타임 시에 발생할 수 있는 null 참조 오류를 컴파일 전에 방지할 수 있게 된다.
void main() { final name = 'gigi'; }
한 번 선언된 값을 변하지 않는 값으로 만들고 싶으면 변수 앞에 final
키워드를 붙여주면 된다. 뒤에 const
키워드가 나올 예정인데, 용도는 동일하나 변수의 값이 상수가 되는 시점이 다르다. final
은 런타임
시에 상수가 된다.
void main() { late final name; name = 'gigi'; }
late
는 final
, var
앞에 사용할 수 있다. 초기 데이터 없이 변수를 선언할 수 있게 해주며 API
를 호출하여 data fetching
을 할 때 유용하다.
사실 late를 사용하지 않아도 초기 데이터 없이 변수를 선언할 수 있으나, 이 친구의 장점은 class 내에서 발휘한다.
class 내의 인스턴스 변수에 late가 없으면 변수 선언과 동시에 값을 할당해야 하고, late가 있으면 선언 후에 할당해도 된다.
void main() { const name = 'gigi'; }
앞서 언급했던 것처럼, const
키워드는 컴파일
시점에 상수로 선언되어 있어야 한다. API를 호출하거나, 사용자가 화면에서 입력해야 하는 값을 사용하는 것은 적절하지 않다. 동적인 값을 사용하려면 final
, var
키워드가 적절하다.