1. dart 예제 설명
1. ex01.dart
//static > heap > stack
class Aniaml {
int id = 1;
//final = readOnly
static final String name = "동물";
}
//static(정적) 메모리에 뜬다.
//일급 객체
String name = "Hello World";
void speak() {
// 메소드 (상태 변경할때)
}
void hello() {
//static 에 떠있다.
//메소드가 아니라 함수다 (기능을 가지는 친구), 상태는 가지고 있지 않다.
//stack 에 뜬다.
int num = 10;
}
// static(전역,정적) 메모리에 뜬다.
// 메소드가 아니고 void main() main 함수이다.
void main() {
print(name);
print(Aniaml.name); // 정적 변수
//int id 는 이제 뜬거다!
Aniaml a = Aniaml();
print(a.id);
}

2. ex02.dart
//main static, 인터프릭터(Interpreter)
void main() {
//4개는 stack에 있다.
//type 있으면 메모리 공간 활당을 할 수 있다.
int n1 = 1;
double d1 = 10.1;
bool b1 = true;
String s1 = "홍길동";
print("정수: ${n1.runtimeType}");
print("실수: ${d1.runtimeType}");
print("부울: ${b1.runtimeType}");
print("문자열: ${s1.runtimeType}");
}

인터프리터(Interpreter)
- Dart는 인터프리터 언어로, 코드를 한 줄씩 해석하고 실행합니다. 이는 개발 중 빠른 피드백과 디버깅에 유리합니다.
- 또한, Dart는 Just-In-Time (JIT) 컴파일과 Ahead-Of-Time (AOT) 컴파일을 모두 지원하여 개발과 배포 단계에서 모두 최적의 성능을 발휘할 수 있습니다.
코드설명
이 코드는 Dart에서 다양한 타입의 변수를 선언하고, 각 변수의 타입을 출력하는 예제이다. 변수의 타입을 명확하게 선언함으로써 Dart가 메모리를 효율적으로 관리할 수 있게 해주고,
runtimeType
을 통해 실제 타입을 확인할 수 있고 주석을 통해 변수들이 스택에 저장된다는 점과 타입의 중요성을 간단히 언급하고 있습니다.3. ex03.dart
void main() {
//type 있으면 메모리 공간 활당을 할 수 있다.
// var = 타입추론
var n1 = 1;
//n1 = "가자";
var d1 = 10.1;
var b1 = true;
var s1 = "홍길동";
print("정수: ${n1.runtimeType}");
print("실수: ${d1.runtimeType}");
print("부울: ${b1.runtimeType}");
print("문자열: ${s1.runtimeType}");
}

코드설명
var
키워드와 타입 추론
var
키워드:var
를 사용하여 변수를 선언하면, Dart는 변수에 할당된 초기값을 바탕으로 타입을 자동으로 추론합니다. 예를 들어,var n1 = 1;
에서는n1
의 타입이int
로 결정됩니다.
- 타입 추론의 장점:
- 코드가 간결해지고 가독성이 향상됩니다.
- 명시적으로 타입을 선언하지 않아도 되므로 개발 속도가 빨라집니다.
- 그러나 타입을 명확히 알고 싶거나 복잡한 타입의 경우에는 명시적으로 타입을 선언하는 것이 좋습니다.
타입 안전성
- Dart는 정적 타입 언어로, 변수의 타입이 컴파일 시점에 결정됩니다. 따라서 타입이 일치하지 않는 값을 할당하려고 하면 컴파일 오류가 발생하여 런타임 오류를 줄일 수 있습니다.
- 예를 들어,
var n1 = 1;
으로 선언된 변수n1
은 이후에 문자열을 할당할 수 없습니다. 이는 코드의 안정성을 높이는 데 도움이 됩니다.
runtimeType
프로퍼티
runtimeType
:- 변수의 실제 타입을 런타임에 확인할 수 있는 프로퍼티입니다.
- 디버깅 시 변수의 타입을 확인하거나, 타입에 따라 다른 동작을 수행할 때 유용하게 사용됩니다.
4. ex04.dart
void main() {
// dynamic 타입은 모든 타입(추상화)을 받을 수 있고 다른 타입으로 변경도 가능하다.
// Object 타입이라고 생각하면 된다.
dynamic n1 = 1;
dynamic n2 = 1;
print("정수 : ${n1.runtimeType}");
print("정수 : ${n2.runtimeType}");
n1 = 10.5;
n2 = "문자열이다";
print("n1 : ${n1.runtimeType}");
print("n2 : ${n2.runtimeType}");
//산술 연산자
print("3%2=${3 % 2}"); // 나머지
print("3~/2=${3 ~/ 2}"); // 몫 구하기
}

5. ex05.dart
//null을 사용 할수 가 없다.(주석 풀어보세요)
//String username = null;
//int usernaem = null;
//null 허용방법
//?연산자라고 선생님께서 부르신다고 하셨다.
String? username = null; //전역 정정 메모리(static), 클래스의 static 영역이 아니다.
//언젠가 들어올 데이터에는
late String username1;
class A {
//heap에 들어가는 메모리
//A(){} 오류가 안나오게 할려면 int? num;을 하면 오류가 생기지 않는다.
//int num;
int? num;
//A(){} 생성자를 만들면 int num은 오류가 나지 않지만 A생성자는 오류가 난다.
A() {}
}
void main() {
print(username);
// 삼항연사자 username이 null이면 임시아이디
print(username ?? "임시아이디");
//if은 실행문이지 표현문이 아니다.
//print(if(username==null){})
}

코드설명
1.널 안전성 (Null Safety)
- Dart의 널 안전성은 **널 참조 오류(null reference error)**를 방지하기 위해 도입되었습니다.
- 널을 허용하지 않는 타입 (
String
,int
등)은null
값을 가질 수 없으며, 컴파일 시점에 이를 검사합니다.
- 널을 허용하는 타입 (
String?
,int?
등)은null
값을 가질 수 있으며, 필요에 따라null
체크를 수행해야 합니다.
2. late
키워드
late
키워드는 변수를 나중에 초기화할 것임을 명시합니다.
- 이를 통해 초기화 시점에 값을 할당하지 않아도 되지만, 사용 전에 반드시 초기화해야 합니다.
- 사용 시 주의사항:
- 초기화 전에 사용하면 런타임 오류가 발생할 수 있습니다.
- 초기화를 보장할 수 있는 로직과 함께 사용하는 것이 좋습니다.
3. 삼항 연산자와 널 병합 연산자
- 삼항 연산자 (
condition ? expr1 : expr2
): - 조건에 따라 두 표현식 중 하나를 선택하여 반환합니다.
- 예:
username != null ? username : "임시아이디"
- 널 병합 연산자 (
??
): - 왼쪽 표현식이
null
이면 오른쪽 표현식을 반환합니다. - 예:
username ?? "임시아이디"
Share article