01 다트 입문하기
사용 도서
[Must Have 코드팩토리의 플러터 프로그래밍]
https://ebook-product.kyobobook.co.kr/dig/epd/ebook/E000006311569
Must Have 코드팩토리의 플러터 프로그래밍 | 최지호(코드팩토리) | 골든래빗(주)- 교보ebook
다트 & 플러터 입문부터 실전 앱 개발 10가지와 인증 / 광고 / 배포까지 , ◆ 다트 3.0 최신 문법과 소셜 로그인, 슈파베이스 연동, 인증 그리고 광고와 배포까지 ◆ 플러터 앱 개발, 이 책 한 권이면
ebook-product.kyobobook.co.kr
1.1 다트 소개
- UI 제작에 최적화됨. 완전한 비동기 언어, 이벤트 기반. 아이솔레이트를 이용한 동시성 기능 제공
- 널 안정성, 스프레드 기능, 컬렉션 if문 등 효율적인 UI 코딩 기능 제공
- 효율적인 개발 환경 제공 (핫 리로드)
- 멀티 플랫폼 로깅 및 디버깅, 실행
- AOT 컴파일(Ahead of Time)이 가능해 어떤 플랫폼에서든 빠른 속도 (다트 가상머신은 JIT 컴파일)
* JIT(Just in Time) : 변경된 코드만 컴파일하는 방식. 핫 리로드 기능으로 개발에 유용
* AOT(Ahead of Time) : 시스텡메 최적화해 컴파일하는 방식. 런타임 성능 개선, 저장공간 절약, 설치, 업데이트 시간 단축. 배포에 적합한 방식
- 자바스크립트로의 완전한 컴파일 지원
- 백엔드 프로그래밍 지원
1.3 기초 문법
1.3.6. final/const를 사용한 변수 선언
변수 값을 처음 선언 후 변경할 수 없게 하는 키워드
final : 런타임 상수
const : 빌드타임 상수. 빌드 타임에 값을 알 수 없으면 사용 불가
1.4 컬렉션
컬렉션 : 여러 값을 하나의 변수에 저장할 수 있는 타입
1.4.1 List
List<타입> 이름 = [ ]
length : 리스트 길이 반환
add() : 리스트에 값을 추가
where() : 리스트에 있는 값들을 순서대로 순회하면서 특정 조건에 맞는 값만 필터링. 매개변수로는 함수를 입력하며, 함수는 기존값을 하나씩 매개변수로 입력받음. 순회가 끝나면 유지된 값들을 기반으로 이터러블이 반환됨
void main() {
List<String> li = ['cado', 'nana', 'woobeol'];
final newList = li.where(
(name) => name == 'cado' || name == 'nana'
);
print(newList); //(cado, nana)
print(newList.toList()); //[cado, nana]
}
map() : 리스트에 있는 값들을 순서대로 순회하면서 값을 변경. 매개변수에 함수 입력하며 함수는 기존값을 하나씩 매개변수로 입력받음. 반환값이 현재값을 대체하며 순회가 끝나면 이터러블이 반환됨
void main() {
List<String> li = ['cado', 'nana', 'woobeol'];
final newList = li.map(
(name) => '아기 $name'
);
print(newList); //(아기 cado, 아기 nana, 아기 woobeol)
print(newList.toList());
}
reduce() : 리스트에 있는 값들을 순회하며 매개변수에 입력된 함수 실행. 순회할 때마다 값을 쌓아가며, 리스트 멤버의 타입과 같은 타입을 반환함
매개변수 2개를 입력받는 함수를 매개변수로 입력받음
순회가 처음 시작될 때 첫번째 매개변수(value)는 리스트의 첫번째 값을 받고, 두번쨰 매개변수(element)는 두번째 값을 받게 됨. 첫 번째 순회 이후로는 첫 번째 매개변수에 기존 순회에서 반환한 값이 들어가고, 리스트의 다음 값이 두번째 매개변수에 입력됨. 즉 리스트 내부의 값들을 점차 더해가는 기능으로 사용.
void main() {
List<String> li = ['cado', 'nana', 'woobeol'];
final allF = li.reduce((value, element) =>
value + ',' + element);
print(allF); //cado,nana,woobeol
}
fold() : reduce()와 동일하게 실행되나 reduce()는 함수가 실행되는 리스트 요소들의 타입이 같아야 하지만 fold()는 어떠한타입이든 반환할 수 있음. 첫번째 매개변수에 시작할 값, 두번째 매개변수에는 reduce()에 썼던 것처럼 작동하는 함수 입력. 단 첫번째 순회 시 value에 첫번째 매개변수에 입력한 시작값이 사용됨. 이후 순회는 reduce()와 동일
void main() {
List<String> li = ['cado', 'nana', 'woobeol'];
final allF = li.fold<int>(0, (value, element) =>
value + element.length);
print(allF); //15
}
1.4.2 Map
Map<키 타입, 값 타입> 이름 = { 키1: 값1, 키2: 값2, ... }
키(key)와 값(value)의 짝 저장. 맵[key] 로 value에 접근
keys : 모든 키를 이터러블로 반환
values : 모든 값을 이터러블로 반환
1.4.3 Set
Set<타입> 이름 = { }
중복 없는 값들의 집합. 각 값의 유일함을 보장
contains() : 값의 존재여부 확인
Set.from(리스트) : 리스트를 Set타입으로 반환. 중복값 제거됨
1.4.4 enum
enum 이름 { ... }
한 변수의 값을 몇 가지 옵션으로 제한. 선택지가 제한적일 때 사용
자동완성이 지원되고 정확히 어떤 선택지가 존재하는지 정의해둘 수 있음.
1.5 연산자
1.5.2 null 관련 연산자
다트 언어에서는 변수타입이 null값을 가지는지 여부를 직접 지정해야 함
- 변수에 null값을 저장하려면 타입 뒤에 ?를 명시해야 함
- 변수에 값 추가 시 ??를 사용하면 기존값이 null일 때만 값이 저장되도록 할 수 있음
void main() {
double? number;
print(number); //null(자동 저장)
number ??= 3;
print(number); //3(기존값이 null이니 3이 저장됨)
number ??= 4;
print(number); //4(기존값이 null이 아니므로 4는 저장되지 않음)
}
1.6 제어문
1.6.3 for문
for...in : 리스트의 모든 값을 순회할 때 사용
void main() {
List<int> numList = [3,6,9];
for(int num in numList) {
print(num);
}
}
1.7 함수와 람다
1.7.1 함수의 일반적인 특징
매개변수를 지정하는 방법
- 포지셔널 파라미터 (순서가 고정된 매개변수) : 입력된 순서대로 매개변수에 값 지정
[ ] 으로 매개변수 기본값 지정 가능
int addNum(int a, [int b = 2]) {
return a+b;
}
void main() {
print(addNum(1)); //3
}
- 네임드 파라미터 (이름이 있는 매개변수) : 순서와 상관없이 매개변수의 이름을 이용해 값 입력. 키와 값 형태로 매개변수 입력
네임드 파라미터 지정시 중괄호 { } 와 required 키워드 사용. (required : 매개변수가 null값이 불가능한 타입이면 기본값을 지정해주거나 필수로 입력해야 한다는 의미) 기본값 적용시 required 키워드 생략 가능.
int addNum({
required int a,
required int b,
}) {
return a+b;
}
void main() {
print(addNum(a: 1, b: 2)); //3
}
- 포지셔널, 네임드 파라미터 섞어서 사용 가능. 섞을 때는 >포지셔널 파라미터를 반드시 먼저 써야 함<
int addNum(
int a, {
required int b,
int c = 4,
}
) {
return a+b+c;
}
void main() {
print(addNum(1, b:3)); //8
}
1.7.2 익명 함수와 람다 함수
이름이 없고 일회성으로 사용되는 함수. 다트에서는 익명 함수와 람다 함수를 구분하지 않음.
익명함수 : (매개변수) { 함수 바디 }
람다함수 : (매개변수) => 단 하나의 스테이트먼트. 가독성이 높아 콜백함수나 리스트의 map(), reduce() 함수 등에서 일회성이 높은 로직을 작성할 때 주로 사용.
1.7.3 typedef와 함수
typedef : 함수의 시그니처(반환값 타입, 매개변수 개수와 타입 등)를 정의하는 값. 함수 선언부를 정의하는 키워드
typedef Op = void Function(int x, int y);
void add(int x, int y){
print('result: ${x+y}');
}
void sub(int x, int y){
print('result: ${x-y}');
}
void main() {
Op oper = add; //Op에 해당되는 시그니처 할당 가능
oper(1,2); //3
oper = sub;
oper(1,2); //-1
}
다트에서 함수는 일급 객체(first-class citizen)이므로 함수를 값처럼 사용할 수 있음
즉 typedef로 선언한 함수를 아래처럼 매개변수로 사용 가능
typedef Op = void Function(int x, int y);
void add(int x, int y){
print('result: ${x+y}');
}
void calc(int x, int y, Op oper){
oper(x,y);
}
void main() {
calc(1,2,add); //3
}