여기서 먼저 알아둬야할 것은 다트는 OOP 언어. 즉, 진정한 객체 지향 언어다. 리마인드하고 다음으로 넘어가자
다트의 다양한 자료형이 있다.
우리가 아는 String
뿐만 아니라 bool
, int
, double
등이 있다.
void main() {
String name = "뿔소";
bool alive = true;
int age = 12;
double money = 69.99;
}
String
은 따옴표로 이루어진, bool
은 true
/false
로 이루어진, int
는 숫자, double
은 소수점까지를 뜻한다.
여기서 특징은 거의 모든 자료형이 Object로 이루어져있다. 엥? 뭐지?! JS랑 TS는 원시형과 참조형(Object)로 나뉘어져 있는데 다 그렇다고?!
왜냐면 다트는 진정한 '객체 지향 언어'이기 때문이다. String
부분인 타입 선언자를 우클릭하고 type definition, 형식 정의로 이동하면은
이와 같은 타입 선언자 특징이 나온다. class
가 보이지 않는가? 바로 객체라는 뜻이다. 다른 선언자들도 마찬가지다. int(eger)
와 double
는 num
을 받은 객체, bool
은 독립적으로 선언된 객체다.
이렇게 만든 클래스들 덕분에 우리는 타입 별 메소드를 사용할 수 있는 것이다.
이제 좀 더 복잡한 자료형을 보겠다.
잠깐! VSC를 사용하고 있다면 리스트 마지막 요소 뒤에
,
를 붙이면 자동으로 포맷팅해준다. 구조가 불편하다면 이 포맷팅을 사용해보자.
JS, TS를 하다왔으면 익숙한 것들이다.
void main() {
var nums = [1, 2, 3, 4];
var nums = [
1,
2,
3,
4,
];
}
var
키워드로 선언 후 리스트 이름, 대괄호와 같은 타입의 값을 넣어주면 된다. TS와 똑같다! 또한 요소 간 중복도 가능하다.
당연히 추가할 때도 같은 타입을 넣어야한다.
이제 List의 메소드를 정리해보자.
당연하겠지만 외우기는 어렵다. 그래서 저렇게 설명을 봐주면 좋고, 어디서 찾아 쓰는지만 알면 된다.
first
/ last
: List 첫번째 / 마지막 요소를 가져다 줌isEmpty
: List가 비어있는지 아닌지를 알려줌add
/ addAll
: List에 새로운 하나의 / 여러개의 요소를 추가함clear
: 전부 비우기contains
: 가지고 있는지 알아내기등등 많으니 알아두자.
Collection for, Collection if를 지원한다. 리스트 안에 if와 for을 집어넣을 수 있다. 예시를 보자.
var giveMeFive = true;
var nums = [
1,
2,
3,
4,
if (giveMeFive) 5,
];
이렇게 쓸 수 있다. 근데 가독성이 안좋아지니 ,
를 붙여 가독성 좋게 포맷팅하면 좋다라고 얘기한 것이다.
이제 더 나아가보면
void main() {
var giveMeFive = true;
var nums = [
1,
2,
3,
4,
if (giveMeFive) 5,
];
// 위의 if (giveMeFive) 5의 의미는 아래와 같음.
// if (giveMeFive) {
// nums.add(5);
// }
print(nums);
}
이렇게 쓸 수 있고, 결과값은 [1, 2, 3, 4, 5]
가 나왔다. 훨씬 직관적이면서도 신기한 기능이다.
for를 이제 봐보자. if는 조건에 따라 리스트에 직접 넣어줄 수 있었다면 for은
void main() {
var oldFriends = ['뿔소', '기린'];
var newFriends = [
'사자',
'늑대',
'코끼리',
for (var friend in oldFriends) "⭐️ $friend",
];
print(newFriends);
}
// [사자, 늑대, 코끼리, ⭐️뿔소, ⭐️기린]
이런 식으로 iterable
객체를 선언하고 for문으로 리스트에 넣어준다면? 해당되는 값들이 들어가 반영됐다!
이 기능이 왜 좋냐면 특히 collection if같은 경우 UI 인터페이스를 만들 때 정말 좋다. 예를 들어 nav bar 객체를 만드는데 로그인 상태와 관련되어 변경할 때 짧게 끝낼 수 있다는 것이다.
for도 시간과 코드 비용을 아껴준다. for문 작성 후 add 해서 리스트를 넣어줘야하는데 리스트 한줄로 끝나니 멋지게 좋다.
Interpolation : 보간법, 사이채움
다트에선 String(text) 안에 변수를 채우는 방법을 뜻한다.
많이 쓸 것이다. 왜냐면 TS할 때도 많이 썼기 때문에..
void main() {
var name = '윤뿔소';
var greeting = '안녕하세요!, 제 이름은 $name에요!';
print(greeting);
}
// 안녕하세요!, 제 이름은 윤뿔소에요!
저렇게 따옴표 안인 String 안에 달러머니 사인을 적고 변수이름을 적으면 나온다. 꼭 사인 뒤에 변수 이름을 적어야한다는 것이다.
되게 편하다! 저렇게 달러사인을 입력하면 나와줘서 편하다. 심지어 계산도 가능하다.
void main() {
var name = '윤뿔소';
var age = 25;
var greeting = '안녕하세요!, 제 이름은 $name에요! 제 나이는 ${age + 3}살이에요';
print(greeting);
}
// 안녕하세요!, 제 이름은 윤뿔소에요! 제 나이는 28살이에요
이런 식으로 중괄호 안에 계산식 적어주면 적용되어서 나온다. 나중에 배우겠지만 프로퍼티 같은 걸 가져올 때도 중괄호를 넣어줘야한다. 쨋든 간단한 걸 불러오기에는 달러와 변수 이름만, 나중에 프로퍼티나 계산식 등 복잡해지면 중괄호를 입력하면 된다. 끝!
TS, JS의 Map 메소드, 이름이 Map인 객체랑 다르다. 오히려 일반 객체에 가까운 자료유형이다. 참고로 파이썬의 딕셔너리와 비슷한 자료유형이다.
예시를 보자.
void main() {
var animals = {
'이름': '뿔소',
'세기': 89.3,
'육식동물': false,
};
}
일반 객체와 같이 중괄호에, 콜론으로 이루어져 있다. 타입도 알아서 지정해준다.
실제로 보니 일반 객체와 더 비슷하지 않는가? 또 타입은 String
, Object
으로 된 Map이다. 앞이 key
, 뒤가 value
를 뜻한다. 즉, 키는 String
으로, 밸류는 String
, double
, bool
이 섞인 짬뽕탕이기에 Object
로 나뉜 모습이다. 왜냐면 모든 자료형이 Object
이기 때문에 그렇다. TS의 any
타입과 비슷하다.
여기서 타입 선언도 강제로도 가능하다. 이렇게 말이다.
void main() {
Map<int, bool> isTrue = {
1: true,
2: false,
3: false,
4: true,
};
}
TS의 interface 같이 타입을 강제하고 다른 건 못들어오게 막을 수 있다. 객체 자체를 계획 짜는 것이다! 추가로 List도 넣을 수도 있다 ㅋㅋㅋ
void main() {
Map<List<int>, bool> isTrue = {
[1, 2, 3]: true,
[2]: false,
[3]: false,
[4]: true,
};
}
신기한 놈이다. 다트는. 또 당연히 List 속 Map도 가능하다. TS에서 많이 썼던 배열 속 객체처럼 말이다.
void main() {
List<Map<String, Object>> isTrue = [
{
'이름': '뿔소',
'세기': 89.3,
'육식동물': false,
},
{
'이름': '사자',
'세기': 99.3,
'육식동물': true,
},
];
}
짠! 근데 이건 객체 지향 언어인 dart에선 그리 권장하지 않는 방식이다. 보통 위 같은 모양을 API 응답 데이터 같은 key와 value를 가지는 구조로 object를 만들 때 사용하지 않는가? 저렇게가 아닌 class
를 이용해서 특정 형태를 가져보도록 배워보자.
또 메소드도 entries
, isEmpty
, keys
, length
, values
, contains
등 있으니 꼭 알아서 활용하자.
Set도 다르지만 쉽다. 바로 콜론 없이 중괄호만 적어주면 된다.
사진같이 말이다. int
로 이루어진 Set
이라고 알 수 있다. 당연히 Set
과 타입 설정을 따로 써줘도 된다.
어 그러면 List랑 괄호만 다르지 같은 거 아닌가요?! 싶다. 여기서 차이점을 말해주겠다.
사진을 보면 1을 3번 추가했음에도 중복이 생기지 않았다. 이게 큰 차이점이다.
Set
은 sequence(순서가 있음)이라고 생각하면 된다. List
랑 같지만 모든 요소가 유니크해야한다. Dart도 그렇게 알고 만들어준다. 즉, List
는 유니크안해도 되면 List
로 넣고, Set
처럼 요소들이 하나만 있어야한다면 Set
객체를 사용하면 된다.
정리하자면
JS Set = Dart Set = Python Set
JS Array = Dart List = Python List
JS Object = Dart Map = Python Dictionary
Map<K, V>
형태로 표기하며, K는 키의 타입, V는 값의 타입.Map<String, int> ages = {
'John': 25,
'Jane': 30,
'Alice': 27,
};
print(ages['John']); // 25
Set<T>
형태로 표기하며, T는 값의 타입.Set<String> fruits = {'apple', 'banana', 'orange'};
fruits.add('kiwi');
print(fruits.contains('banana')); // true
따라서, Map은 키-값 쌍의 컬렉션으로 값을 검색할 때 사용하며, Set은 중복되지 않은 값들의 컬렉션으로 중복 검사가 필요한 경우 사용.
화법이 코딩애플이 생각나는걸요 ㅋㅋㅋ