❮
[번역/요약] Dart Language samples
20190916
12가지 예제를 통해서 기본적인 특징만 소개합니다.
모든 앱은 main()
함수를 가집니다. top-level(다른 객체에 속하지 않은, 파일 단계) print()
함수를 이용해서 콘솔에 텍스트를 출력합니다.
void main(){
print('Hello, World!');
}
명시적으로 타입을 지정하지 않아도 타입 추론을 통해서 type-safe한 코드를 쓸 수 있습니다.
var name = 'Voyager I';
var year = 1977;
var antennaDiameter = 3.7;
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
var image = {
'tags':['saturn'],
'url':'//path/to/saturn.jpg'
};
평범합니다. C 스타일입니다.
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;
}
그 밖에도 break, continue, switch, case, assert 같은 것들이 있습니다.
함수도 평범합니다. 함수를 쓸 때 매개변수와 리턴값의 타입을 지정할 것을 권장합니다.
int fibonacci(int n)
{
if(n == 0 || n == 1) return n;
return fibonacci(n - 1) + finbonacci(n - 2);
}
var result = fibonacci(20);
=>
문법을 이용하면 함수를 포함하는 단문을 쉽게 만들 수 있습니다. 특히 익명 함수를 매개변수로 전달할 때에 유용합니다.
flyByObjects.where((name) => name.contains('turn')).forEach(print);
where() 의 매개변수로 익명함수 (name) => name.contains('turn') 을 전달하는 것을 볼 수 있습니다.
매우 평범하게 // /**/ 를 사용합니다.
/// 는 커스텀 함수나 클래스를 만들 때 도큐먼트에서 보일 주석입니다.
다른 라이브러리의 API를 사용하려면 import 문을 사용합니다.
import 'dart:math';
import 'package:test/test.dart';
import 'path/to/my_other_file.dart';
다음은 3개의 속성(properties), 2개의 생성자(constructors), 하나의 메소드를 갖는 클래스 예제입니다.
class Spacecraft {
String name;
DateTime launchDate;
Spacecraft(this.name, this.launchDate) {
}
Spacecraft.unlaunched(String name) : this(name, null);
int get launchYear =>
launchDate?.year;
void describe() {
print('Spacecraft: $name');
if (launchDate != null) {
int years =
DateTime.now().difference(launchDate).inDays ~/
365;
print('Launched: $launchYear ($years years ago)');
} else {
print('Unlaunched');
}
}
}
var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
voyager.describe();
var voyager3 = Spacecraft.unlaunched('Voyager III');
voyager3.describe();
다트는 단일 상속을 사용합니다.
class Orbiter extends Spacecraft {
num altitude;
Orbiter(String name, DateTime launchDate, this.altitude)
: super(name, launchDate);
}
믹스인은 다중 클래스 계층 구조에서 코드를 재사용하는 방법입니다.
class Piloted {
int astronauts = 1;
void describeCrew() {
print('Number of astronauts: $astronauts');
}
}
클래스에 믹스인의 능력을 더하려면, 클래스를 확장할 때 with 믹스인을 같이 하면 됩니다.
class PilotedCraft extends Spacecraft with Piloted {
}
이렇게 하면 PilotedCraft는 astronauts 필드와 describeCrew() 메소드도 가지게 됩니다.
(다중 상속 아닌 다중 상속)
10. 인터페이스와 추상 클래스 / interfaces and abstract classes
다트는 interface
키워드가 없습니다. 모든 클래스는 암시적으로 인터페이스를 정의합니다. 즉, 어떠한 클래스라도 implements 할 수 있습니다.
class MockSpaceship implements Spacecraft {
}
추상 클래스는 concrete 클래스에 의해서 extended 또는 implemented 됩니다. 추상 클래스는 추상 메소드(몸체가 없는) 를 포함할 수 있습니다.
abstract class Describable {
void describe();
void describeWithEmphasis() {
print('=========');
describe();
print('=========');
}
}
Descriable을 확장하는 클래스는 describeWithEmphasis() 메소드를 가지고, 여기 호출하고 있는 describe() 추상 메소드는 확장한 클래스의 구현을 따릅니다.
콜백 지옥을 벗어나서 가독성 높은 코드를 작성하기 위해서 async와 await을 사용합니다.
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';
}
}
예외를 일으키려면 throw
를 사용합니다.
if(astronauts == 0){
throw StateError('No astronauts.');
}
예외를 처리하려면 try
문과 on
또는 catch
를 사용합니다.
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
는 동기적인 코드와 async
함수 안에 있는 코드 모두에서 잘 동작합니다.