Dart 언어 란?
•
자바스크립트 대체로 나왔으나 typescript 가 나오면서 떡락
•
Flutter에서 공식언어로 정하면서 떡상 시작
•
사람들이 말하는 Dart를 배워야하는 이유
◦
유지 보수가 쉽다.
◦
배우기 쉽다.
◦
생산력을 증가하게 돕는다.
◦
유연하고 활용성이 높다.
◦
reactive programming 을 전제로 만들어졌다.
•
객체 지향 지원
•
자바스크립트로 컴파일해서 웹 제작 가능
•
네이티브 코드로 컴파일해서 Android 나 IOS용 앱 제작 가능
•
개인적인 경험
◦
자바스크립트랑 자바를 섞어놓은 느낌...?
◦
안배워도 될만큼 쉽다고는 하지만 그래도 알아두면 좋을것같다.
개발 환경
DartPad
•
웹기반 공식 에디터
Android Studio
개발환경 설정 참고
언어 배우기
기본 구조 및 중요개념
•
모든 변수는 객체
•
모든 객체는 Object 클래스로부터 상속
•
제너릭 타입 지원
•
public, protected, private 키워드가 없음. private 하려면 이름 앞에 _ 붙인다.
•
패키지 불러오기
◦
import 'package.dart' as name; package를 name으로 불러옴
◦
import 'package.dart' show test; package중 test만 불러옴
•
동기 , 비동기 처리 가능
•
주석은 // /* */ 으로 가능
•
print('$a + $b = ${$a + $b}');
변수
// 타입 변수명 = 초기값
String name = "ycha";
// 타입 지정 없이 사용
// 다른 타입 못가짐
var balance = 1000;
balance = "yeah"; //Error
// 타입 변경 가능한 타입
dynamic balance = 1000; //이러면 속도가 느림
Object balance = 1000;
balance = "yeah"
// num 은 int, double 상위 타입
// double 에서 int로 타입 캐스팅 불가능
num a = 10;
int b = 10;
double c = 10.4;
b = c; //Error
// 상수
final int NAME = "ycha";
final int NUM = get(); // 런타임에서 상수화
const int NAME = "ycha"; // 컴파일에서 상수화
//함수
Function sum = (a, b) {
return a + b;
};
Dart
복사
•
json decode 하고 무슨 타입인지 모를때 var 사용을 추천
•
런타임, 컴파일에서 상수화 ?
◦
둘다 무조건 선언과 초기화를 동시에 해야한다.
main() {
const int c_num = 10;
final int f_num = 10;
const int c_num_2; //오류!!!
num_3 = 10;
}
Dart
복사
◦
const 는 처음부터 초기값이 고정되어있고,
◦
final 은 함수 또는 클래스에 따라서 초기값이 바뀔수있다.
finalTester(int newNum) {
final int num = newNum;
print("final : ");
print(num);
}
constTester(int newNum) {
const int num_2 = 10;
const int num = newNum; //오류!
print("const : ");
print(num);
}
main() {
finalTester(10);
constTester(10);
}
Dart
복사
◦
클래스에서 생성자를 이용한 final 초기화
◦
일반 변수처럼 할당하지 못하고, 아래의 2가지 경우처럼 초기화해야함
class FinalTester {
final int num;
FinalTester.init1(int input) : num = input;
FinalTester.init2(this.num);
FinalTester.init3(int input) {
this.num = input; //오류
}
}
main() {
var tmp = FinalTester.init2(20);
print(tmp.num);
}
Dart
복사
•
const 위치 에 따른 차이점
◦
값 복사 붙여넣기가 아니라 실제로는 해당 값의 포인터를 담고 있다.
main() {
List<int> num = [1, 2, 3];
num.add(4);
print(num);
}
// [1, 2, 3, 4]
Dart
복사
◦
num 에는 list 객체의 주소값이 저장되어있는것
◦
const [1, 2, 3] 은 리스트 1 2 3 이 고정이기 때문에 값을 수정하지 못한다.
◦
const num 은 num 의 값이 고정이다.
▪
num이 가리키고 있는 값도 수정하지 못한다.
▪
[1, 2, 3] 에 4를 추가하면 [1, 2, 3, 4] 라는 새로운 객체가 생기고 그게 num_1 에 들어가기떄문에 오류가 나는게 아닌가....
main() {
const num_1 = [1, 2, 3];
var num_2 = const [1, 2, 3];
const num_3 = const [1, 2, 3];
num_1 = [] // 오류
num_1[0] = 4 // 오류 (c 랑 다르다..!)
num_1.add(4); // 오류 (c 랑 다르다..!)
num_2 = []; // 이건 됨
num_2[0] = 4 // 오류
num_2.add(4); // 오류
// num_1 와 동일함
num_3 = [] // 오류
num_3[0] = 4 // 오류
num_3.add(4); // 오류
print(num_1);
print(num_2);
print(num_3);
}
Dart
복사
◦
final 로 하면 또 차이점이 있다!
main() {
var temp = [1, 2, 3];
final num_1 = temp;
temp = [];
temp.add(4);
//num_1 = []; // 오류
num_1.add(4);
print(temp);
print(num_1);
}
// 출력
// [4]
// [1, 2, 3, 4]
Dart
복사
함수
•
자바스크립트와 비슷하게 함수도 객체
•
변수가 함수를 참조가능
•
함수의 인자로 함수전달 가능
void printElement(int element) {
print(element);
}
var list = [1, 2, 3];
main() {
//매개변수로 함수 전달
list.forEach(printElement);
//변수에 함수 할당
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');
}
Dart
복사
•
익명함수
main() {
var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});
//화살표 표기법을 이용하여 단축 가능
list.forEach((item) => print('${list.indexOf(item)}: $item'));
}
Dart
복사
•
클로저도 지원!
Function makeAdder(num addBy) {
return (num i) => addBy + i;
}
void main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
Dart
복사
•
선택 매개변수
int sumUp(int a, int b, int c) => a + b + c;
// 위치 선택 매개변수 []
int sumUpToFive(int a, [int b, int c, int d, int e]) {
int sum = a;
if (b != null) sum += b;
if (c != null) sum += c;
if (d != null) sum += d;
if (e != null) sum += e;
return sum;
}
// 이름 선택 매개변수 {}
// required 어노테이션으로 필수 매개변수임을 명시가능
getAddress (String city, { String distruct, String zipCode = '1122'}) {
}
//Dart를 사용하면 매개 변수를 대괄호로 묶어 선택적으로 지정할 수 있습니다.
int total;
total ??= 0;
total = sumUp(1, 2, 3);
total = sumUpToFive(1, 2);
total = sumUpToFive(1, 2, 3, 4, 5);
print('$(getAddress('서울', district: '강남'))')
Dart
복사
•
타입 생략 가능
add() { // int 타입 생략 가능
return 10;
}
Dart
복사
•
함수 오버로딩 가능
연산자 및 조건식
// 타입검사 연산자
Person p1 = employee as Person // 형변환
if (employee is Employee) // 특정 객체인지
if (employee is! Employee) // 아닌지
// 타입 찍어보고 싶을때
List<dynamic> a = [~];
print(a[0].runtimeType);
// 조건 표현식
(a > 0) ? 'y' : 'n';
employee?.name // 좌항이 null이면 null, 아니면 우항
employee.name ?? 'new name' // 좌항이 null 이면 우항
// 캐스케이드
Employee employee = Employee()
..name = 'kim'
..setAge(25);
employee.name = 'kim'; // 위의 코드와 동일
// assert
assert(a > b); //거짓일경우 에러 발생 (debug mode만 가능)
// for
for (dynamic each in test)
print(each);
Dart
복사
클래스
•
자바의 객체 와 비슷함
•
private, public 두개밖에 없음
◦
정확히 하면 내부에서 private으로 인식하는게 아니라
◦
p._age 처럼 점 뒤에 언더바를 못쓰게함
class Person {
String name;
int _age; //private 변수
getName() {
return name;
}
_sleep() { //private 메서드
print('sleep');
}
}
var student = Person(); // new 키워드 없어도 됨
student.name = "Kim";
C++
복사
생성자
class Person {
String name;
int age;
final String fname;
final num fage;
Person() {
// 기본 생성자
// 없으면 자동으로 생성
}
Person() : name = 'Kim' { // 바로 할당 가능한 친구들
// 무거운 친구들
}
Person(String name) {
// Error!
}
Person(this.name, this.age) {
// 이런것도 되네
}
Person.init() {
// 생성자 여러개 할떄
}
Person.initName(String name) : this(name, 20);
// 리다이렉팅 생성자
// this.name = name, this.age = 20 과 동일
const Person(this.name, this.age);
// 클래스를 상수처럼 쓰기 가능
}
}
class Student extends Person { // 상속
// Person 의 기본 생성자 호출
}
var p = Person.init();
Dart
복사
•
팩토리 생성자도 있음. 자세한 설명은 참고 확인
◦
팩토리 패턴에서 쓰임
◦
싱글턴 패턴에서 쓰임
상속
class Person {
String name;
Person.init();
showinfo() {
print('person $name');
}
}
class Student extends Person {
Student() : super.init();
showinfo() {
print('student $name')
}
}
Dart
복사
추상 클래스
•
implement 여러개 가능
abstract class Person {
eat();
}
class Developer implements Person {
eat() {
print('eat');
}
}
main() {
Developer p = Developer(); // 여러개 implement 할때는 이렇게
Person p = Developer();
p.eat();
}
Dart
복사
Getter & Setter
class Person {
String _name;
String get name => _name;
set name(String name) => _name = name;
}
main() {
Person p = Person();
p.name = 'kim';
print(p.name);
}
Dart
복사
•
null 처리는 참고 확인
•
Stream 관련 연산 함수들을 작성할 때 getter 많이 쓰임
컬렉션 (자료구조)
// List
List<dynamic> colors = ['Red', 'Blue', 'Green', 1, 2, 3];
colors.add('Yellow');
colors.remove('Red');
colors.map((v) {print(v)})
// Set - 중복허용 X
Set<dynamic> colors = {'Red', 'Blue', 'Green', 1, 2, 3};
colors.add('Yellow');
colors.remove('Red');
// Map
Map<int, String> testMap = {
1:'Red',
2:'Blue',
3:'Green'
}
testMap[4] = 'Yellow';
testMap.update(1, (value) => 'NewRed', ifAbsent: () => 'NewColor');
Dart
복사
•
기타 메소드 및 프로퍼티는 참고 확인
제너릭
class Student<T extends Person> { //매개변화 타입 제한
void add(T value) {
value.getName();
}
}
class Person {
T getName<T>(T param) {
return param;
}
}
var p = Person();
p.getName<String>('kim');
Dart
복사
비동기
•
isolate 있음
•
다른 언어와 마찬가지로 await async future 있음