크로스 플랫폼 앱 개발에 도전하고 싶어졌다.
React Native와 Flutter 두 개의 선택지에서 고민하다가 여러 자료를 찾아본 후 Flutter를 선택했고, Flutter에서 공식적으로 지원하는 언어인 Dart를 맛만 봤다. (니꼬의 무료강의)
깊게 공부한 것은 아니지만 결론부터 말하자면 C#, JAVA를 경험해본 나에게는 크게 어렵진 않았다.
Dart는 2011년에 처음 발표된 구글에서 개발한 프로그래밍 언어로, 모든 플랫폼에서 빠른 앱을 개발하기 위해 클라이언트에 최적화된 언어이다. Dart의 목표는 앱 프레임워크를 위한 유연한 실행 런타임 플랫폼을 가진 멀티 플랫폼 개발을 위한 가장 생산적인 프로그래밍 언어를 제공하는 것이라고 한다.
객체지향 언어(OOP)
Java
/ C#
과 유사한 클래스 기반 객체지향 방식을 지원하고 모든 값이 객체로 취급되는 특징이 있다.
다양한 플랫폼 지원
Flutter 프레임워크를 사용하여 Android
, ios
, 웹
, 데스크톱 애플리케이션
을 단일 코드베이스로 개발이 가능하고 서버 및 CLI 프로그램
도 개발이 가능하다.
JIT(Just-In-Time) & AOT(Ahead-Of-Time) 컴파일
개발 중에는 JIT컴파일을 사용하여 빠른 실행과 핫 리로드 기능을 지원하고, 배포 시에는 AOT컴파일을 활용해 네이티브 코드로 변환, 실행 속도를 최적화해준다.
Null Safety(Null 안전성)
null참조로 인해 발생하는 오류를 방지하기 위해 ?
, !
, late
키워드를 활용하는 Null Safety기능을 제공한다.
https://dartpad.dev/
위 사이트에 접속해 바로 Dart를 맛 볼 수 있다.
우선 Hello world부터 찍어보자.
void main() {
print('Hello, World!');
}
그만 알아보자.
가장 먼저 다른 언어들과 달랐던 점은 String
, int
, double
, bool
등 명시적인 데이터 타입들을 제공하면서 동시에 var
또한 제공한다는 점이다.
class Human {
String name;
int age;
}
void main() {
var name = 'zai';
var age = 28;
var zai = Human();
}
Dart에서 권장하는 방식은 함수나 메서드 내부에 변수를 선언할 때는 var
키워드를 사용하고, 클래스의 Property를 선언할 때에는 명시적인 타입을 지정해는 것이다.
추가로 위의 코드처럼 name
이라는 변수를 var
로 선언함과 동시에 'zai'
라는 문자열 리터럴을 넣어줬다면 저 name
변수에는 문자열 리터럴만 들어갈 수 있다.
변수가 선언되는 동시에 Dart는 리터럴을 통해 해당 변수의 데이터타입을 추론하고 확정하기 때문이다.
만약 아래코드처럼 dart
라는 변수를 var
로 선언만 하고 그 다음에 리터럴을 넣는다면?
void main() {
var dart;
dart = 'cool~';
dart = 1234;
dart = true;
}
이 경우 dart
라는 변수는 dynamic
이라는 데이터 타입으로 추론되기 때문에 어떤 데이터 타입의 리터럴도 문제없이 받아들인다.
이번에는 상수에 대해 알아보자. Dart에서 상수를 선언할 때는 final
, const
두 가지 방법이 있다.
void main() {
final String name = 'zai';
const String lang = 'dart';
}
두 타입 모두 리터럴을 한 번만 설정할 수 있는 상수이지만, 차이점은 final
은 런타임에서 할당이 가능하지만 const
는 런타임에서 할당이 불가하고 컴파일을 할 때 값이 확정되어 있어야 한다.
그 말은 즉,
void main() {
const now = DateTime.now();
}
이런 식으로 const 상수를 선언할 수 없다.
✅ 컴파일 타임에 확정되는 상수 값은 const
를 사용, 동적으로 할당되는 상수 값은 final
을 사용
다음은 late
키워드이다.
late
키워드는 변수(상수)에 값을 나중에 넣어주어야 할 때 사용한다.
void main() {
late final String name;
// Do~~~~~~ somthing!
name = 'zai';
}
name
이라는 상수를 선언만 해주고 나중에 얻는 값을 해당 상수에 넣어 줄 때 사용한다고 이해하면 된다. API를 통한 작업을 할 때 많이 사용한다고 한다.
다음은 '2. Dart의 주요 특징' 에서 언급한 Null Safety에 관한 부분이다.
void main() {
String name = 'zai';
name = null; // * 이 부분에서 Error 발생 *
}
위 코드와 같이 선언된 변수에 null값을 리터럴로 넣어주면 에러가 발생한다. 실제로 코딩을 해본 사람이라면 예상치 못한 null로 인한 문제를 겪어봤을 것이다. Dart는 그런 문제를 방지하기 위해 코드가 실행되기 전에 컴파일러가 해당 버그를 잡아주는 Null Safety 기능를 제공한다.
그렇다면 null값을 허용해주기 위해선 어떻게 해야될까?
void main() {
String? name = 'zai';
name = null; // * 이젠 Error 안나용~ *
}
이렇게 자료형 뒤에 ?
를 써주면 name
변수는 null값을 허용하겠다는 뜻이다.
Dart에는 Collection if라는 기능이 있다. 아래에 List를 하나 만들었다.
void main() {
var numbers = [1, 2, 3, 4];
}
특정 조건에 따라 해당 리스트에 새로운 값이 들어갈 수도, 들어가지 않을 수도 있는 코드를 작성해보면
void main() {
var giveMeFive = true;
var numbers = [1, 2, 3, 4];
if (giveMeFive) {
numbers.add(5);
}
}
이런 식으로 코딩을 해야겠지만 Dart의 Collection if를 활용해서 코드를 작성하게 되면
void main() {
var giveMeFive = true;
var numbers = [
1,
2,
3,
4,
if (giveMeFive) 5,
];
}
이렇게 아~주 간단하게 구현할 수 있다.
String interpolation은 문자열에 변수를 추가하는 방법이다.
JS에서 문자열을 백틱(`)으로 감싸고 ${ }로 변수를 추가하는 그것!
Dart에서도 $를 사용하는 것은 동일하지만 백틱은 필요없다.
아래는 Dart의 String interpolation이다.
void main() {
var name = 'zai';
var greeting = 'Hello everyone, my name is $name, nice to meet you!';
print(greeting);
}
보다시피 JS와 다르게 변수 그 자체를 넣어줄 때는 { }를 생략해도 된다. 하지만, 변수를 계산해서 출력해야되는 상황에서는 JS와 동일하게 { }로 감싸줘야된다. 아래는 그 예시다.
void main() {
var name = 'zai';
var age = 26;
var greeting = "Hello everyone, my name is $name, and I'm ${age + 2}.";
print(greeting); // 출력결과 : Hello everyone, my name is zai, and I'm 28.
}
Collection for도 제공한다.
void main() {
var oldFriends = ['nico', 'lynn'];
var newFriends = [
'lewis',
'ralph',
'darren',
for(var friend in oldFriends) "♥️ $friend",
];
print(newFriends); //출력 결과 : [lewis, ralph, darren, ♥️ nico, ♥️ lynn]
}
간단한 함수를 작성할 때 유용하게 쓰일 수 있는 Fat arrow syntax를 소개한다.
변수 a
, b
를 받아 두 값을 더한 값을 return해주는 함수를 만들자.
int plus(int a, int b) {
result = a + b;
return result;
}
여기서 한 단계 줄인다면
int plus(int a, int b) {
return a + b;
}
이렇게 코드를 간소화 할 수 있다. 하지만 Dart는 이것도 귀찮았나보다. 아래의 코드가 Fat arrow syntax를 사용한 함수이다.
int plus(int a, int b) => a + b;
분량 조절 실패.. 이 외에도 Named Parameters, Optional Opsitional Parameters, QQ Operator, Typedef, Enums, Mixins 등 유용하고 알아두면 좋을 Dart의 문법들이 많다. 나중에 시간이 된다면 추가로 포스팅하겠지만, 블로그 쓰는게 마냥 쉽지가 않다.
Dart를 공부하고 Flutter로 앱 개발을 도전하고자 하는 사람이 있다면 니꼬의 무료강의를 들어보는 것을 추천한다.
오늘은 여기서 마친다.