Search
Duplicate

Dart 삽질

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 있음

참고