Dart
≡ 목차 (Table of Contents)
이 글은 다트(Dart) 프로그래밍 언어의 소개 및 간단한 문법 등을 정리하는 글이다.
Dart
구글이 개발한 프로그래밍 언어다. 그래서 구글이 아니면 잘 안 쓴다. 그런데 구글에서도 Flutter를 제외하면 거의 안 쓴다.
네이티브 코드가 아니라 VM(Virtual Machine) 위에서 돌아간다. 컴퓨팅 자원을 낭비하는 정말 최악의 특징이다. 문법적으로 줄 끝에 세미콜론을 찍어야 하는 빌어먹을 특징까지 가지고 있다.
그 외에 async - await 등 다양한 부분에서 Javascript와 유사한 점이 종종 보이는 것 같다.
그나마 다행인 점은 정적 타이핑 언어라는 점이다.
개인적으로 싫어하는 언어이지만 써야 하기 때문에 억지로 남기는 메모가 이어진다.
엔트리 포인트(Entry Point)
void main() { print('Hello World!'); }
C와 비슷하지만 print 함수가 자동으로 개행 문자를 붙인다는 점에서 다르다. 반환 타입도 없는데 *NIX 와는 어울리지 않겠다는 의미로 보면 될까?
참고로 문자열 표현은 Javascript와 비슷하게 따옴표와 쌍 따옴표 둘 다 이용할 수 있다.
타입(Types)
타입 체크
인스턴스의 타입이 무엇인지 확인하기 위해서 Python과 비슷하게 is
를 사용할 수 있다.
instance is Type
문자열 조합(String Interpolation)
print('foo is $foo');
만약 클래스 프로퍼티나 특정 구문의 실행 결과를 문자열에 넣으려면 중괄호로 감싸주면 된다.
print('foo bar is ${foo.bar}');
함수(Function)
함수를 정의하는 몇 가지 예를 보자.
someProcedure() { // ... } anotherProcedure(value) { print('$value'); } fooLambda() => print('blah blah'); bool isOdd(value) { return value % 2 != 0; } String nameCard({name: String, age: int}) { return '$name, $age'; }
반환 타입이 없는 것은 그냥 void
타입 함수라고 생각하자.
화살표 함수는 Javascript의 것과 상당히 유사하다. 아예 return
이 생략되어 있는 형태인 점도 잘 생각해두자.
마지막 함수의 매개 변수 선언하는 쪽에는 중괄호가 둘러싸고 있는데, named field 형태를 구현하는 방법으로 역시 빌어먹을 Javascript에서 쓰는 방법과 유사하다. 아니 언어를 새로 만드는 데 이딴 것도 그냥 문법으로 새로 만들면 되잖아? 이해가 안 되네.
루프(Loop)
기본적은 for-loop 모양은 C 식과 거의 동일하다.
for (int i=0; i < 5; i++) { print('current = $i'); }
forEach
는 아래와 같이 리스트와 섞어서 쓰면 편하다.
// ['alpha', 'beta', 'gamma'].forEach((e) => print(e)); ['alpha', 'beta', 'gamma'].forEach((e) { print(e); });
Map과 Filter
Map은 리스트에 그냥 쓰면 된다.
[1, 2, 3].map((e) => 'number $e');
그런데 Filter는 좀 다른 것 같다.
[1, 2, 3, 4, 5].where((e) => e % 2 == 0).toList()
where()
의 결과는 반복 가능한 타입이라 바로 iteration 해도 상관은 없는데, 일반 리스트로 얻기 원한다면 toList()
로 변환해 줘야 한다. 즉, where 자체가 filter와 동일하다고 볼 수 있다.
클래스(Class)
기본 형태
기본적인 모양은 이런 식이다.
class SomeClass extends SomeParentClass { // Property and Default Value String name = 'Conrad'; // Constructor SomeClass(String anotherName) { name = anotherName; } // Named Constructor SomeClass.anonymous() { name = 'Nonamed Who'; } // Method void whoami() { print('I am $name'); } // Method - usage of 'this' void updateName(String name) { this.name = name; } ... // override method @override void nag() { super.nag() ... } }
상속에 오버라이드에 생성자 패턴에 뭐 기본적인 사항은 다 있는 것 같다.
Setter 그리고 Getter
class SomeClass extends SomeParentClass { int age = 0; ... // bool get koreanAge { // return age + 1; // } bool get koreanAge => this.age + 1; set koreanAge(int korAge) { this.age = korAge - 1; } }
화살표 함수 형태를 쓰면 역시 단축이 가능하다.
콜백(Callback)
Function
키워드를 이용하면 콜백 함수 프로퍼티를 선언할 수 있다.
Function(int param1, String param2)? onSomeAction;
패러미터가 없다면 아예 괄호 전체를 없애버려도 관계는 없다.
콜백 핸들러를 정의하는 방법은 기존대로 하면 된다.
onSomeAction = (param1, param2) => { ... }
위는 클로저 문법으로 콜백 핸들러를 구현했다. 물론 정적 함수나 메서드로 구현해서 심볼을 넘겨줘도 잘 동작한다.
추가로 리턴 값이나 패러미터가 필요 없다면 VoidCallback
을 사용할 수도 있다.
VoidCallback? onSomeAction;
Dart 베타 버전 (with Homebrew)
Homebrew를 사용한다면 베타 채널로 쉽게 스위칭이 가능하다.
brew install dart-beta
다만 기존에 dart가 설치되어 있다면 기존 것을 unlink 해야 한다.
brew unlink dart
안정 버전으로 되돌릴 때는 dart-beta
를 unlink하고 dart
를 다시 링크하면 된다.
brew unlink dart-beta brew link dart