App/Flutter

[Dart] Dart Language sample - Dart부터 시작하는 Flutter 앱 개발 1

메바동 2021. 6. 3. 10:54
728x90

💡 본 포스팅은 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의 예외에 대해 알아볼 수 있습니다.

728x90