Dart는 구글에서 개발한 오픈 소스 프로그래밍 언어로, 주로 클라이언트 애플리케이션을 개발하는 데 사용됩니다. Dart는 웹, 모바일, 데스크탑, 서버 등 다양한 플랫폼에서 실행되는 애플리케이션을 만들 수 있도록 설계되었습니다.
1. JIT vs AOT
JIT
실행 시 컴파일: JIT 컴파일은 프로그램을 실행하는 실시간에 소스 코드를 기계어로 변환합니다. 즉, 코드가 실행될 때 필요한 부분만 즉시 컴파일되어 처리됩니다.
AOT
실행 전에 컴파일: AOT 컴파일은 프로그램이 실행되기 전에 전체 코드를 기계어로 변환합니다. 이로 인해 실행할 준비가 된 완전한 바이너리가 생성됩니다.
Dart에서의 JIT:
- Dart에서는 개발 중에 JIT 컴파일을 사용하여 빠른 수정과 테스트가 가능하게 합니다. 예를 들어, Flutter의 Hot Reload 기능은 JIT 컴파일 덕분에 매우 빠른 코드 변경 및 테스트가 가능합니다.
Dart에서의 AOT:
- Dart는 릴리즈 빌드에서 AOT 컴파일을 사용합니다. 이는 Flutter 앱이 실제 기기에서 매우 빠르게 실행되도록 돕습니다. 앱이 배포된 후에는 런타임 중 추가적인 컴파일 없이 최적화된 상태로 실행됩니다.
2. 변수
정적 & 동적 타입 언어:
- Dart는 정적 타입과 동적 타입을 모두 지원합니다.
- 개발자가 필요에 따라 타입을 명시하거나 생략할 수 있으며, 코드 작성 시 타입을 추론하여 정적 타입 검사를 수행합니다.
변수는 int, double, bool, String 를 지원합니다.
Dart 언어는 타입 추론을 지원합니다. 값이 들어올 때 타입을 추론하여 변수를 초기화합니다. var과
dynamic의 차이는 var은 타입 변경이 불가능하고 dynamic은 타입 변경이 가능합니다.
int a = 10; // 정적 타입 지정
var b = "hello"; // Dart가 자동으로 타입을 추론3. 함수
함수(Function)는 클래스 외부에 존재하고 메서드(Method)는 클래스 내부에 존재합니다.
또한, Dart에서는 오버로딩이 지원되지 않습니다.
1) 익명함수
익명 함수 (Anonymous Function):
- 이름이 없는 함수이며, 일반적인 함수 선언처럼 중괄호(
{})를 사용합니다.
- Dart에서 함수는 일급 객체로 취급되므로, 익명 함수를 변수에 할당하거나 다른 함수에 전달할 수 있습니다.
- 여러 줄의 코드가 필요할 때 사용됩니다.
2) 람다식
람다식 (또는 화살표 함수, Fat Arrow Function):
- 익명 함수의 간결한 표현입니다.
- 함수의 내용이 한 줄일 때 사용할 수 있으며,
=>연산자를 사용하여 표현합니다.
- 중괄호와
return키워드가 생략됩니다. 한 줄의 결과가 자동으로 반환됩니다.
// 오버로딩 지원이 안됨
// 타입생략 가능 -> 타입 추론
void add(n1, n2) {
print(n1 + n2);
}
// return 타입에 var는 불가능, dynamic은 가능
int minus(n1, n2) {
return n1 - n2;
}
Function f = (n1, n2) {
// 익명 함수
return n1 * n2;
};
// 람다 표현식(한줄로 표현해야함)
Function f2 = (n1, n2) => n1 * n2;
void main() {
int result = minus(2, 1);
print(result);
print(f(2, 3));
}
- 익명 함수는 중괄호와
return키워드를 사용하여 여러 줄의 코드를 작성할 수 있습니다.
- 람다식은 한 줄로 표현될 수 있는 간단한 함수에 사용하며, 중괄호 대신
=>를 사용하고 자동으로 반환합니다.
4. 이니셜라이즈
**이니셜라이즈(initialize)**란 프로그래밍에서 변수, 객체, 데이터 구조 등을 사용할 수 있도록 초기 상태를 설정하는 과정을 의미합니다. 이 과정을 통해 변수나 객체는 기본값이나 특정 값으로 설정되어, 프로그램에서 적절히 동작할 수 있게 됩니다. 이니셜라이즈는 프로그램이 오류 없이 실행되도록 중요한 역할을 합니다.
int a; // 초기화되지 않은 상태
a = 10; // 이니셜라이즈
var b = 20; // 선언과 동시에 이니셜라이즈class Cat {
String name;
int age;
String color;
int thirsty;
Cat(this.name, this.age, this.color, this.thirsty);
}
class Dog {
String name;
int age;
String color;
int thirsty;
Dog(String name, int age, String color, int thirsty)
: this.name = name,
this.age = age,
this.color = color,
this.thirsty = thirsty;
}
Cat클래스는 축약된 생성자 문법을 사용합니다. 생성자에서 직접 필드와 매개변수를this키워드로 자동 매핑하는 방식입니다.- 더 간결하고 직관적인 코드를 제공하며, 필드를 초기화하기 위해 중복 코드를 작성하지 않아도 됩니다.
Dog클래스는 초기화 목록(initializer list)을 사용합니다. 이는 명시적으로 생성자 매개변수를 필드에 할당하는 방식으로, 약간 더 길지만, 더 명확하게 각 필드를 초기화할 수 있습니다.
5. 선택적 매개변수
**선택적 매개변수 (optional parameters)**는 함수나 생성자를 호출할 때 반드시 제공할 필요가 없는 매개변수입니다. 선택적 매개변수는 기본값을 가지거나, 제공되지 않을 경우 null로 처리될 수 있습니다. Dart에서는 위치 기반 선택적 매개변수와 이름 기반 선택적 매개변수 두 가지 방식으로 선택적 매개변수를 지원합니다.
class Dog {
int age;
String name;
Dog({required this.age, required this.name}); // required를 붙이면 무조건 값을 넣어줘야함
}
class Cat {
int? age;
String? name;
Cat(
{this.age,
this.name = "토토"}); // 선택적 매개변수로 null 값이 들어갈 수 있다 -> 타입에 ?가 있어야 한다
void cry() {
print("야옹");
}
String toString() {
return "age : ${age}, name : ${name}";
}
} // default 값을 name = "토토" 가지게 된다
void main() {
Dog d = Dog(name: "토토", age: 10);
Cat c = Cat(age: 10)..cry();
print(d);
print(c);
}선택적 매개변수를 사용할 경우 null 값이 들어갈 수 있기 때문에, 타입에서 ?를 붙여주어야 한다. 또는, this.name = “토토” 로 정의하면 name의 default 값을 “토토”로 가지게 되어 변수 age만 생성해주면 된다.
반대로 ?타입을 입력하지 않을 경우에 required를 붙여 무조건 값을 넣는다는 것을 알려줘야 한다.
선택적 매개변수를 사용한다면 JAVA에서 Builder패턴처럼 굳이 생성하지 않더라도 내가 원하는 변수를 순서에 상관없이 값을 집어 넣을 수 있다.
- 유연한 함수 호출: 함수 호출 시 모든 매개변수를 반드시 제공하지 않아도 되므로 더 유연하게 코드를 작성할 수 있습니다.
- 가독성 향상: 특히 이름 기반 선택적 매개변수는 매개변수의 의미를 명확히 하고, 코드의 가독성을 높이는 데 도움이 됩니다.
- 기본값 제공: 기본값을 제공할 수 있어, 매개변수 값이 제공되지 않았을 때도 예상 가능한 값을 사용할 수 있습니다.
Cascade(생성 시 바로 호출 가능한 기능)
.. 연산자를 사용하면 코드 한 줄로 객체를 변수로 넘겨주면서 객체가 가진 함수를 호출할 수 있는
유용한 표기법입니다.

6. Null 처리 방법
// null 처리 방법
int? findById(int id) {
return id == 1 ? 1 : null;
}
void main() {
int r1 = findById(1)!; // null이 아님을 확실할때 사용하는 연산자
print(r1);
int r2 = findById(5) ?? 0; // null 대체 연산자
print(r2);
double? r3 = findById(5)?.toDouble() ??
0; // findById()가 null이 아니면 toDouble()실행, null이면 0
}1) ! : "null 억제 연산자" 또는 "null assert 연산자”
Dart에서 ! 기호는 "null 억제 연산자" 또는 "null assert 연산자"라고 불립니다. 이 연산자는nullable 변
수나 nullable 표현식을 사용할 때 해당 값이 null이 아님을 명시적으로 나타내는데 사용됩니다.
2) ?? : “null 병합 연산자”
이 연산자를 사용하면 변수나 표현식의 값이 null인 경우에 대체 값을 지정할 수 있습니다. null 병합 연산자를 사용하여 코드를 더 간결하고 안전하게 작성할 수 있습니다.
3) ? : “null check 연산자”
null 체크 연산자 ( ? )는 null 값일 수 있는 객체의 속성이나 메서드에 안전하게 접근하는 데 사용됩니다. 이 연산자는 null 참조 오류를 방지하고 코드를 더 견고하게 만듭니다.
Share article