다트(Dart)는 구글에서 만든 객체 지향 언어입니다. 플러터를 사용하기 위해서는 다트 언어를 사용해야 합니다.. 우리가 다트를 배우는 유일한 이유입니다...👀 이 글은 다트를 한시간안에 뽀갤 수 있는 글입니다! 🎯 ㄱㄱ
Dart programming language
Dart is a client-optimized language for fast apps on any platform
dart.dev
🎯 다트의 특징
1. Optimized for UI
다트는 async-await를 제공하여 User Interface를 만드는 데에 최적화되어 있습니다. 또한, 다트의 문법은 UI 구성 요소를 표현하기에 매우 최적이라고 합니다.
2. Productive development
개발 생산성을 올리는 다트의 특징은 여러가지가 있지만, 그 중 가장 특징이 되는 점은 Null safety가 언어 자체적으로 된다는 점입니다. 현재 자바나 C++에서는 코드가 runtime에서 null을 참조하게되면 RTE(Runtime Exception)이 발생하게 됩니다. 이는, 프로그램이 런타임에서 죽어버리는 현상이며 매우 좋지 않습니다. 하지만 자바나 C++로 작성된 프로그램들이 종종 겪게되는 문제입니다. 다트는 언어 자체가 이를 방지해주는 특징을 갖고 있습니다. 어떻게 Null safety를 제공하는지는 이후 내용에서 보실 수 있습니다.
또한, 다트와 Flutter를 함께 사용하면 Hot reload 기틍을 통해 어플리케이션의 수정 사항을 빠르게 반영할 수 있습니다. 개발 중에 코드를 수정하면 어플리케이션이 자동으로 다시 빌드되고 변경 사항이 즉시 반영됩니다. 개발자가 실시간으로 코드를 변경하면 이를 바로 눈으로 확인하며 개발할 수 있음을 뜻합니다. 이런 특징 또한 UI 개발에 최적화되어 있다고 볼 수 있습니다.

3. Fast on all platforms
다트는 Dart web과 Dart native라는 2개의 컴파일러를 가지고 있습니다. Dart web은 dart로 작성한 코드를 javascript로 변환해주는 컴파일러이고, Dart native는 다트 코드를 플랫폼의 네이티브 기계어로 변환해주는 컴파일러입니다. 즉, 특정 운영체제(Windows, macOS, Linux)에서 직접 실행할 수 있는 기계코드로 변환해줍니다. 따라서 한 번 작성한 다트 코드로 웹, 모바일 앱(IOS, Android), 데스크탑 앱(Windows, Linux, Mac)으로 모두 컴파일 할 수 있습니다.

이 글을 보는 분들이라면 단순히 다트를 사용하기 위해서 이 글을 보는 분들은 아마 없을 것입니다. 다트를 배우는 궁극적인 목적은 바로 플러터에 있을 것입니다.😅 그렇다면 플러터는 왜 다트를 사용할까요?
1. 다트는 JOT 컴파일러와 AOT 컴파일러를 모두 지원합니다.
- JIT (Just On Time) 컴파일러: 소스코드를 실행하는 도중에 코드를 실시간으로 컴파일합니다. 따라서 Hot reloading을 가능하게하여 어플리케이션 실행 중에 코드 수정 사항을 빠르게 반영할 수 있습니다. 개발자는 어플리케이션을 다시 빌드할 필요없이 변경한 코드를 바로바로 눈으로 확인할 수 있습니다. 다만, dart virtual machine위에서 동작하기 때문에 느리다는 것이 단점입니다.
- AOT (Ahead Of Time) 컴파일러: 컴파일을 먼저하고, 그 결과인 바이너리 코드(기계어)를 배포합니다. 앱을 배포할 때는 dart VM을 사용하지 않고 AOT 컴파일러를 사용합니다. 따라서 JIT 컴파일러를 사용하는 것과는 다르게 미리 컴파일된 기계 코드를 실행하기 때문에 빠르게 동작할 수 있습니다.
이 두가지 컴파일러를 지원한다는 것은 개발과 배포에 모두 장점을 가지고 있다는 것을 의미합니다. 즉, 개발할 때는 JIT 컴파일러를 사용하여 코드 변경 사항을 바로바로 확인하고, 배포할 때는 AOT 컴파일러를 사용하여 빠르게 동작하는 앱으로 배포하는 것이지요!
2. 다트와 플러터는 모두 구글에서 만들어졌기 때문에 다트 언어로 플러터 프레임워크를 사용하기 위한 최적의 환경입니다. 즉, 프레임워크를 최적화하기 위해서 언어를 수정할 수 있습니다. 이는 언어와 프레임워크가 협력관계에 있다는 의미이며 엄청난 효율성을 제공할 수 있습니다. (실제로 원래에는 다트가 AOT 컴파일러를 가지고 있지 않았는데, 다트 개발 팀에서 플러터 개발 팀에게 AOT 컴파일러를 만들어달라고 해서 만들어졌다고 합니다..ㅎ)
그럼, 본격적으로 다트 언어에 대해 알아보겠습니다. 기본적인 내용은 아주 간략히 보고, 다트만의 특징적인 부분을 중점적으로 보았습니다.
🎯 변수
- 변수는
var
키워드로 생성하여 컴파일러가 타입을 추론하도록 할 수 있고, 명시적으로 타입을 명시해줄 수 있습니다.

dynamic
키워드는 여러 타입을 가질 수 있는 변수에 사용합니다.

- 다트는 Null safety를 강제합니다. 따라서 기본적으로 모든 변수는
null
값을 가질 수 없습니다. 하지만 프로그래밍에서null
의 역할은 아주 유용하기 때문에null
자체를 없애는 것은 좋지 않습니다.null
값을 가질 수 있는, 즉 nullable한 변수는 타입 뒤에?
를 붙여서 만들어줍니다.

late
modifier는 변수를 생성한 후, 나중에 값을 초기화해야할 때, 사용합니다.

final
키워드는 변수의 값이 한 번 할당되면 이후에 수정할 수 없도록 합니다. (다른 언어(java, js 등)에서의const
와 같습니다.)const
키워드는final
과 똑같이 동작하지만, compile time에 정해지는 값입니다. 그러니까final
키워드보다도 더 단단한 상수같은 개념입니다. 즉, 절대 바뀌지 않고 컴파일할 때 값을 이미 알고있을 때 사용합니다. 앱스토어에 앱을 배포하기 전에 이미 알고있는 값에만 사용할 수 있습니다.
🎯 Types
- Dart의 built-in type으로는
Numbers
(int
,double
),String
,bool
,List
,Set
,Map
,null
등이 있습니다. - 이외에도 Object, Enul, Future, Stream, Iterable, Never, dynamic, void가 있습니다.
- Object는 Null 타입을 제외한 모든 클래스의 부모 클래스입니다.
- Enum은 모든 enum의 부모 클래스입니다.
- dynamic은 동적 타입으로 다른 static type과 달리 컴파일 시에 타입 검사를 수행하지 않고 실행할 때 변수나 표현식의 실제 타입을 동적으로 결정합니다. 따라서 어떤 타입의 값이든 할당할 수 있습니다.
- 다트는 3가지 Collection(List, Set, Map)을 사용할 수 있는데, 이런 collection에서 사용할 수 있는 Control-flow operator가 있습니다. collection을 만들 때,
if
(collection if)와for
(collection for)을 사용하여 만들 수 있습니다.

- typedef는 사용자 정의 타입을 만들 때 사용하는 키워드입니다. alias를 만들 수 있습니다.

🎯 Function
- 함수 정의 형태는 다른 언어들과 비슷합니다.
- function body가 한 줄일때는 fat arrow를 사용하여
return
문을 대신할 수 있습니다.

- 함수를 정의할 때,
{param1, param1, ...}
처럼 작성하여 named parameter를 명시해줄 수 있습니다.required
키워드로 함수 정의 시 꼭 받아야하는 인자를 명시해줄 수 있습니다.required
키워드가 없는 파라미터는 optional한 파라미터로, default값을 정의해주어 사용할 수 있습니다.
(아래 코드에서name
과age
는 필수 parameter로,country
는 optional parameter로 정의되어 있습니다.)

🎯 Class
- 다트는 완전한 객체지향언어입니다. 다트에서 클래스의 개념은 중요합니다❗️
- 기본적인 클래스 생성과 사용하는 방법은 자바같은 객체지향 언어와 비슷합니다.
- 클래스 내의 멤버 변수를 정의할 때는 var 키워드를 사용하지 않고 꼭 타입을 명시해주어야 합니다.
- 클래스 메서드 안에서의 this는 사용하지 않는 것이 권고됩니다.

- 생성자(Constructor)를 만드는 방법도 다른 언어와 비슷합니다. 다트에서는 단축 생성자를 통해 타입 지정없이 바로 멤버 변수 초기화가 가능합니다. 생성자의 이름은
ClassName
또는ClassName.identifier
로 정의할 수 있습니다.

- 함수에서 named parameter를 지정한 방식과 동일하게 Class constructor에서도
{ }
로 감싸주어 named parameter를 지정할 수 있습니다. 생성자에서 꼭 받아야 하는 parameter는required
키워드를 사용합니다. 생성자의 body가 필요한 때는 colon(:
)을 사용하여 body를 명시해줄 수 있습니다.
(아래 코드에서는 3개의 생성자가 존재합니다. 첫번째 생성자는 4개의 parameter를 모두 넘겨주어야 하고,Player.createBluePlayer()
와Player.createRedPlayer()
는team
과xp
멤버변수는 생성자 안에서 기본값으로 설정되는 생성자입니다.)

- 클래스 상속도 다른 객체지향 언어들과 비슷합니다. 자식클래스는
extends
키워드를 통해 부모 클래스의 모든 property와 method를 상속받습니다.

- 다트에서는
Mixin
이라는 생성자가 없는 클래스를 사용할 수 있습니다. 클래스는with
키워드 뒤에Mixin
을 명시하여 사용할 수 있으며,Mixin
의 property와 method를 가져다 사용할 수 있습니다.

'flutter' 카테고리의 다른 글
[Flutter] 기본적인 UI 만들기 (Feat. 플러터의 미친 개발 환경) (2) | 2023.06.21 |
---|---|
[Flutter] Test Drive (앱 구동 시켜보기) (0) | 2021.05.17 |
[Flutter] 시작하기 + 설치 + Editor 설정 방법 (0) | 2021.05.17 |
댓글