💡 본 포스팅은 Dart - Language sample을 번역기로 번역하여 정리한 글입니다.
👋 Hello World
모든 앱은 main() 함수가 있습니다. 콘솔에 텍스트를 표시하려면 print() 함수를 사용하세요.
void main() {
print('Hello World!');
}
📦 변수 (Variables)
Type Safe 한 Dart에서도 타입 추론 덕분에 대부분의 변수에는 명시적 타입이 필요하지 않습니다.
var name = 'mebadong';
var year = 2021;
var antennaDiameter = 3.7;
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
var image = {
'tags': ['saturn'],
'url': '//path/to/saturn.jpg'
};
Dart Tour에서 기본값, final과 const 키워드 그리고 정적 타입을 포함한 Dart의 변수에 대해 알아볼 수 있습니다.
🕹️ 제어문
Dart는 일반적인 제어문을 지원합니다.
if (year >= 2001) {
print('21st century');
} else if (year >= 1901) {
print('20th century');
}
for (var object in flybyObjects) {
print(object);
}
for (int month = 1; month <= 12; month++) {
print(month);
}
while (year < 2016) {
year += 1;
}
Dart Tour에서 break, continue, switch와 case 그리고 assert를 포함한 Dart의 제어문을 알아볼 수 있습니다.
⚙️ 함수 (Function)
각 함수의 인수(arguments)와 반환 값(return value)을 지정하는 것이 좋습니다. 알아보기
int fibonacci(int n) {
if (n == 0 || n == 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
var result = fibonacci(20);
=> (화살표) 구문은 단일 문이 포함된 함수에 유용합니다. 이 구문은 익명 함수를 인수로 전달할 때 특히 유용합니다.
flybyObjects.where((name) => name.contains('turn')).forEach(print);
이 코드는 익명 함수(where()의 인수)를 보여주는 것 외에, 함수를 인수로 전달할 수 있음을 보여줍니다. 최상위 함수 print()는 forEach()의 인수입니다.
Dart Tour에서 선택적 매개 변수, 기본 매개 변수 값 그리고 렉시컬 스코프(lexical scope)를 포함한 Dart의 함수를 알아볼 수 있습니다.
📝 주석
Dart의 주석은 일반적으로 //입니다.
// This is a normal, one-line comment.
/// This is a documentation comment, used to document libraries,
/// classes, and their members. Tools like IDEs and dartdoc treat
/// doc comments specially.
/* Comments like these are also supported. */
Dart Tour에서 문서 도구의 작동 방식을 포함한 Dart의 주석을 알아볼 수 있습니다.
⬅️ import
다른 라이브러리에 정의된 API에 접근하려면 import를 사용합니다.
// 핵심 라이브러리 가져오기
import 'dart:math';
// 외부 패키지에서 라이브러리 가져오기
import 'package:test/test.dart';
// 파일 가져오기
import 'path/to/my_other_file.dart';
Dart Tour에서 라이브러리 접두사, 표시 및 숨기기, deferred 키워드를 통한 게으른 로딩(lazy loading)을 포함한 Dart의 라이브러리 및 가시성(visibility)을 알아볼 수 있습니다.
✔️ 클래스
다음은 세 개의 속성, 두 개의 생성자 및 한 개의 메서드가 있는 클래스의 예입니다. 속성 중 하나는 직접 설정할 수 없으므로 변수 대신 getter 메서드를 사용하여 정의합니다.
class Spacecraft {
String name;
DateTime? launchDate;
// 읽기 전용 non-final 속성
int? get launchYear => launchDate?.year;
// 멤버를 할당하기 위한 syntactic sugar가 있는 생성자
Spacecraft(this.name, this.launchDate) {
// 초기화 코드
}
// 기본 생성자로 전달하는 명명된 생성자
Spacecraft.unlaunched(String name) : this(name, null);
// 메서드
void describe() {
print('Spacecraft: $name');
// 형승격(Type promotion)은 getter에서 동작하지 않습니다.
var launchDate = this.launchDate;
if (launchDate != null) {
int years = DateTime.now().difference(launchDate).inDays ~/ 365;
print('Launched: $launchYear ($years years ago)');
} else {
print('Unlaunched');
}
}
}
Spacecraft 클래스를 다음과 같이 사용할 수 있습니다.
var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
voyager.describe();
var voyager3 = Spacecraft.unlaunched('Voyager III');
voyager3.describe();
Dart Tour에서 초기화 목록 및 선택적 new와 const, 리다이렉션 생성자(redirecting constructors), 팩토리 생성자(factory constructors), getter, setter 등등을 포함한 Dart의 클래스를 알아볼 수 있습니다.
🧻 열거형 (Enums)
열거형은 미리 정의된 값 또는 인스턴스를 열거하는 방법으로 해당 유형의 다른 인스턴스가 있을 수 없도록 하는 방법입니다.
다음은 미리 정의된 planet 타입의 간단한 목록을 정의하는 간단한 열거(enum)의 예입니다.
enum PlanetType { terrestrial, gas, ice }
다음은 행성을 설명하는 향상된 enum 선언의 예로, 정의된 일련의 상수 인스턴스, 즉 태양계의 행성들이 있습니다.
// 태양계의 다른 행성을 열거하는 enum
// 및 일부 속성
enum Planet {
mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
// ···
uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),
neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);
// 상수 생성 생성자
const Planet (
{required this.planetType, required this.moons, required this.hasRings});
// 모든 인스턴스 변수는 final
final PlanetType planetType;
final int moons;
final bool hasRings;
// 향상된 열거형은 getter 및 기타 메서드를 지원
bool get isGiant =>
planetType == PlanetType.gas || planetType == PlanetType.ice;
}
Planet enum은 다음과 같이 사용할 수 있습니다.
final yourPlanet = Planet.earth;
if (!yourPlanet.isGiant) {
print('Your planet is not a "giant planet".');
}
Dart Tour에서 향상된 enum 요구 사항, 자동 도입 속성, 열거 된 값 이름에 액세스, switch문 지원 등을 포함하여 Dart의 enum에 대해 알아볼 수 있습니다.
🖥️ 상속
Dart에는 단일 상속을 받을 수 있습니다.
class Orbiter extends Spacecraft {
double altitude;
Orbiter(String name, DateTime launchDate, this.altitude)
: super(name, launchDate);
}
Dart Tour에서 택적 @override 어노테이션 등을 포함한 Dart의 클래스 확장에 대해 알아볼 수 있습니다.
🤝 믹스인(Mixin)
믹스인(Mixin)은 여러 클래스 계층 구조에서 코드를 재사용하는 방법입니다. 다음은 믹스인 선언입니다.
mixin Piloted {
int astronauts = 1;
void describeCrew() {
print('Number of astronauts: $astronauts');
}
}
클래스에 믹스인의 기능을 추가하려면 믹스인으로 클래스를 확장합니다.
class PilotedCraft extends Spacecraft with Piloted {
// ...
}
PilotedCraft는 이제 astronauts 필드와 describeCrew() 메서드를 가지고 있습니다.
Dart Tour에서 Dart의 믹스인에 대해 알아볼 수 있습니다.
📋 인터페이스와 추상 클래스(abstract classes)
Dart에는 인터페이스 키워드가 없습니다. 대신 모든 클래스는 암시적으로 인터페이스를 정의합니다. 따라서 모든 클래스를 구현할 수 있습니다.
class MockSpaceship implements Spacecraft {
// ...
}
Dart Tour에서 Dart의 암시적 인터페이스에 대해 알아볼 수 있습니다.
구체적인 클래스로 확장 (또는 구현)할 추상 클래스를 작성할 수 있습니다. 추상 클래스는 추상 메서드(빈 본문을 포함)가 포함할 수 있습니다.
abstract class Describable {
void describe();
void describeWithEmphasis() {
print('=========');
describe();
print('=========');
}
}
Describable을 확장하는 모든 클래스는 describeWithEmphasis() 메서드를 가지는데, 이는 확장자에 구현된 describe() 메서드를 호출합니다.
Dart Tour에서 Dart의 추상 클래스와 메서드에 대해 알아볼 수 있습니다.
🔌 비동기(Async)
async와 await를 사용하여 코드를 콜백 헬(callback hell)을 피하고 코드를 더 읽기 쉽게 만듭니다.
const oneSecond = Duration(seconds: 1);
// ...
Future<void> printWithDelay(String message) async {
await Future.delayed(oneSecond);
print(message);
}
위 방법은 다음과 같습니다.
Future<void> printWithDelay(String message) {
return Future.delayed(oneSecond).then((_) {
print(message);
});
}
다음 예제에서 볼 수 있듯이 async와 await는 비동기 코드를 읽기 쉽게 하는데 도움이 됩니다.
Future<void> createDescriptions(Iterable<String> objects) async {
for (var object in objects) {
try {
var file = File('$object.txt');
if (await file.exists()) {
var modified = await file.lastModified();
print(
'File for $object already exists. It was modified on $modified.');
continue;
}
await file.create();
await file.writeAsString('Start describing $object in this file.');
} on IOException catch (e) {
print('Cannot create description for $object: $e');
}
}
}
또한 async*을 사용하면 스트림을 보기 좋게 만들 수 있습니다.
Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {
for (var object in objects) {
await Future.delayed(oneSecond);
yield '${craft.name} flies by $object}';
}
}
Dart Tour에서 비동기 함수, Future, Stream 그리고 비동기 루프(await for)를 포함한 Dart의 비동기 지원에 대해 알아볼 수 있습니다.
⚠️ 예외(Exceptions)
예외를 발생시키려면 throw를 사용합니다.
if (astronauts == 0) {
throw StateError('No astronauts.');
}
예외를 잡으려면 on 또는 catch (혹은 둘 다)와 함께 try 문을 사용합니다.
try {
for (var object in flybyObjects) {
var description = await File('$object.txt').readAsString();
print(description);
}
} on IOException catch (e) {
print('Could not describe object: $e');
} finally {
flybyObjects.clear();
}
위 코드는 비동기식입니다. try는 동기 코드와 비동기 함수에 대해 모두 작동합니다.
Dart Tour에서 스택 추적(stack traces), rethrow, 그리고 오류와 예외의 차이를 포함한 Dart의 예외에 대해 알아볼 수 있습니다.
'App > Flutter' 카테고리의 다른 글
[Dart] Dart Language tour - Dart부터 시작하는 Flutter 앱 개발 2 (0) | 2021.07.27 |
---|---|
[Flutter] flutter doctor - CocoaPods 1.9.3 out of date (1.10.0 is recommended) 에러 해결하기 (0) | 2021.05.26 |