avocado8 2024. 4. 25. 02:14

 

사용 도서

[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
}