이번 여름 방학에는 감사하게도 SKT FLY AI 3기에 참여하게 됐다!
교육기간 중 마지막 3주동안에 프로젝트를 진행하게 되는데, 글쎄 클라이언트 개발자가 없는 것....
그렇게 플러터를 배워보기로 했다
이 글은 최지호님의 코드팩토리의 플러터 프로그래밍을 보고 정리한 글입니다.
구글이 2011년 10월 GOTO 컨퍼런스에서 공개
자바스크립트를 대체하려는 시도를 했지만 웹 개발에 혼란을 가져온다는 여론을 극복하지 못하고
결국 다트 언어를 자바 스크립트로 완전 컴파일 가능하게 하는데 그쳤다.
하지만 현재 플러터의 인기에 힘입어 모바일 영역에서 다트언어가 큰 각광을 받고 있다.
➡️ 개발 시 사용
void main(){
print("Welcome to DuDu's velog");
}
dart lib/main.dart
명령어 실행var 변수명 = 값
형식으로 선언
✅ 타입 추론 기능 제공 → 명시적으로 타입 선언 불필요
✅ 한번 추론된 타입은 고정됨
void main() {
var name = "DuDu";
print(name);
//변경가능
name = "velog";
print(name);
}
✅ 변수의 타입이 고정되지 않음
void main() {
dynamic name = "DuDu";
print(name);
//type 변경 가능
name = 2071003;
print(name);
}
❌ 처음 선언 후 변수 값을 변경할 수 ❌
void main() {
//코드가 실행되는 시간
final DateTime now = DateTime.now();
print(now);
}
void main() {
//에러
const DateTime now = DateTime.now();
print(now);
}
var 키워드를 사용하면 자동으로 타입을 유추할 수 있지만,
직접적으로 명시해주면 더욱 직관적이여서 유지보수가 편함
String
int
double
bool
여러 값을 하나의 변수에 저장할 수 있는 타입
✅ 서로의 타입으로 자유롭게 형변환이 가능
여러 값을 순서대로 한 변수에 저장할 때 사용
void main() {
List<String> duduFoodList = ['떡볶이', '마라탕', '치킨', '쌀국수'];
print(duduFoodList);
print(duduFoodList[0]);
print(duduFoodList[3]); //Last element
//Print Length of List
print(duduFoodList.length);
//Change value
duduFoodList[3] = "분짜";
print(duduFoodList);
}
➡️ 리스트 길이는 length로 확인 가능
List에 값을 추가할 때 사용
void main() {
List<String> duduFoodList = ['떡볶이', '마라탕', '치킨', '쌀국수'];
duduFoodList.add("케이크");
print(duduFoodList);
}
List에 있는 값들을 순서대로 순회하면서 특정 조건에 맞는 값만 필터링하는데 사용
void main() {
List<String> duduFoodList = ['떡볶이', '마라탕', '치킨', '쌀국수'];
final newList = duduFoodList.where(
(food) => food == '떡볶이' || food == '마라탕',);
//iterable
print(newList);
//Change to List
print(newList.toList());
}
List에 있는 값들을 순서대로 순회하면서 값을 변경 가능
void main() {
List<String> duduFoodList = ['떡볶이', '마라탕', '치킨', '쌀국수'];
final newFood = duduFoodList.map(
(food) => '두두가 좋아하는 $food',); //모든 값 앞에 '두두가 좋아하는' 추가
//iterable
print(newFood);
//Change to List
print(newFood.toList());
}
✅ 두개의 매개변수 입력
void main() {
List<String> duduFoodList = ['떡볶이', '마라탕', '치킨', '쌀국수'];
final allFood = duduFoodList.reduce(
(value, element) => value + ', '+element);
//Return Type of List's element == String
print(allFood); //떡볶이, 마라탕, 치킨, 쌀국수
}
✅ 2개의 매개변수
void main() {
List<String> duduFoodList = ['떡볶이', '마라탕', '치킨', '쌀국수'];
final allFood = duduFoodList.fold<int>( //int형 반환
0, (value, element) => value +element.length);
print(allFood); //11
}
key와 value의 짝을 저장
순서대로 값을 저장하는데 중점을 둔 List와 달리,
✅ 키를 이용해 원하는 값을 빠르게 찾는 데 중점을 둠
void main() {
Map<String, String> dictionary = {
'Welcome' : '환영하다',
'to' : '에',
'DuDu\'s' : '두두의',
'velog':'벨로그'
};
print(dictionary['DuDu\'s']);
print(dictionary['velog']);
}
void main() {
Map<String, String> dictionary = {
'Welcome' : '환영하다',
'to' : '에',
'DuDu\'s' : '두두의',
'velog':'벨로그'
};
print(dictionary.keys); //Iterable
print(dictionary.values.toList()); //List
}
중복 없는 값들의 집합
Set<타입> 세트이름
형식으로 생성
중복을 방지하므로 유일한 값들만 존재하는 것을 보장
void main() {
Set<String> duduFood = {'떡볶이', '마라탕', '치킨', '쌀국수', '떡볶이'}; //떡볶이 중복
print(duduFood);
print(duduFood.contains("마라탕")); //마라탕 있는지 확인
print(duduFood.toList()); //Set -> List
List<String> duduFood2 = ['마라탕', '치킨', '치킨'];
print(Set.from(duduFood2)); //List -> Set
}
✏️ 컬렉션 타입들의 진정한 장점은 서로의 타입으로 형변환하며 나타남
- Set에 toList() → List
- Map에 .keys.toList || .values.toList() → List
- Set.from() → 어떤 리스트든 set으로 변환 가능
(물론 set의 특성에 따라 중복값은 제거됨)
한 변수의 값을 몇가지 옵션으로 제한
선택지가 제한적일 때 사용!
String으로 완전 대체할 수 있지만,
enum은 기본적으로 자동완성이 지원되고 정확히 어떤 선택지가 존재하는지 정의해둘 수 있기 때문에 유용하다!
enum Status{
approved,
pending,
rejected,
}
void main() {
Status status = Status.approved;
print(status);
}
다른 언어에서도 사용하는 기본 산수 기능 제공
+
-
*
/
%
++
--
+=
-=
*=
/=
null = 아무것도 없음
(0은 0이라는 값을 가짐)
타입 뒤에 ?
를 추가해줘야 null값 저장 가능
void main() {
//타입 뒤에 ?를 명시 == null값 가질 수 있음
double? num1 = 1;
num1 = null;
//double num2 = null; //ERROR
}
null을 가질 수 있는 변수에 새로운 값을 추가할 때
??
사용하면 기존에 null인 때만 값이 저장되도록 할 수 있음
void main() {
double? num; //자동으로 Null
print(num);
num ??= 3; // 기존값 == null → 변경
print(num);
num ??= 10; //기존값 == 3 → 변경X
print(num);
//??와 = 를 띄어쓰면 오류
}
다른 언어와 동일
>
<
>=
<=
!=
==
is
사용
void main() {
int a = 1;
print(a is int); //True
print(a is String); //False
print(a is! int); //False
print(a is! String); //True
}
&&
||
원하는 조건을 기준으로 다른 코드를 실행하고 싶을 때 사용
if, else if, else문의 순서대로 괄호 안에 작성한 조건이 true이면 해당 조건의 코드 블록이 실행된다.
입력된 상수값에 따라 알맞은 case 블록을 수행
break
키워드를 사용하면 switch문 밖으로 나갈 수 있다.
✅case 끝에 break
를 사용해야한다.
빼먹으면 컴파일 에러남.
enum과 함께 사용하면 유용하다.
여러번 반복해서 실행할 때 사용
for과 동일하게 반복적인 작업 실행 시 사용
do while문의 경우 반복문을 실행한 뒤에 조건을 확인한다.
void
키워드 사용int addNum(int a, int b){
return a+b;
}
void main() {
print(addNum(1,7));
}
이름이 있는 파라미터
지정하려면 중괄호 {}
와 required
키워드 사용
✏️ addNum
함수를 네임드 파라미터 방식으로 변환해보자!
int addNum({required int a, required int b}){
return a+b;
}
void main() {
print(addNum(a:1,b:7));
}
✅
required
키워드
매개변수가 널값이 불가능한 타입이면 기본값을 지정해주거나 필수로 입력해야한다!
는 의미..
✏️ 그렇다면 기본 값을 갖는 포지셔널 파라미터를 지정해보자
int addNum( int a, [ int b = 2 ]){
return a+b;
}
void main() {
print(addNum(1));
}
\
✏️ 그렇다면 기본 값을 갖는 네임드 파라미터!
int addNum({required int a, int b=2}){
return a+b;
}
void main() {
print(addNum(a:1));
}
‼️ 포지셔널과 네임드를 섞어서 사용하는 것도 가능함
다만, 포지서녈 파라미터가 네임드보다 반드시 먼저 위치할 것
int addNum(int a , {required int b, int c = 7}){
return a+b+c;
}
void main() {
print(addNum(1, b:4, c: 4));
}
공통점
통상적으로 많은 언어에서 익명함수와 람다함수를 구분하고 있지만
dart에서는 구분하지 않는다.
▶️ 기본적인 형태
(매개변수){
함수 바디
}
▶️ 리스트의 모든 값을 더하는 함수
void main() {
List<int> nums = [1,2,3,4,5];
final allMembers =nums.reduce((value, element){
return value+element;
});
print(allMembers);
}
▶️ 기본적인 형태
(매개변수) => 단 하나의 스테이트먼트
▶️ 리스트의 모든 값을 더하는 함수
void main() {
List<int> nums = [1,2,3,4,5];
final allMembers =nums.reduce((value, element) => value + element);
print(allMembers);
}
typedef
typedef Operation = void Function(int x, int y);
✅ 다트에서 함수는 일급 객체(First-class citizen)이므로 값처럼 사용할 수 있음
따라서 다음과 같이 매개변수로 넣어서 사용!
typedef Operation = void Function(int x, int y);
void add (int x, int y){
print('결괏값 : ${x+y}');
}
void calculate(int x, int y, Operation oper){
oper(x,y);
}
void main(){
calculate(1, 2, add); //add함수를 매개변수로
}
▶️ 예시코드
void main(){
try{
final String name = 'DuDu';
//에러가 발생하지 않으므로 정상출력
print(name);
}catch(e){
print(e);
}
}
▶️ throw
를 이용해 에러 발생
void main(){
try{
final String name = 'DuDu';
//고의적 에러 발생
throw Exception('It is a wrong name');
print(name);
}catch(e){ //에러 발생 -> catch 출력
print(e);
}
}