Introduction to Dart

힐링코더·2023년 9월 2일

다트 A-Z

목록 보기
5/6

다트 소개
내용

Hello World
변수
제어 흐름 문장
함수
주석
Imports
클래스
Enum
상속
믹스인
인터페이스와 추상 클래스
Async
예외 처리
중요한 개념
추가 리소스


이 페이지는 다트 언어의 주요 기능을 샘플을 통해 간단히 소개합니다.

다트 언어에 대해 더 자세히 알아보려면 왼쪽 메뉴의 "언어" 아래에 나열된 각 주제 페이지를 방문하세요.

다트의 핵심 라이브러리를 다루는 내용은 "라이브러리 투어"를 확인하세요. 더 실전적인 소개를 원한다면 Dart 첫 단계 코드랩을 방문해보세요.


Hello World

모든 앱은 실행이 시작되는 최상위 main() 함수가 필요합니다. 명시적으로 값을 반환하지 않는 함수는 void 반환 타입을 갖습니다. 콘솔에 텍스트를 표시하려면 최상위 print() 함수를 사용할 수 있습니다:

void main() {
  print('Hello, World!');
}

다트에서 main() 함수에 대해 더 자세히 알아보려면 명령행 인수에 대한 선택적 매개변수를 포함한 Dart의 main() 함수에 대해 더 읽어보세요.


변수

타입 안전한 Dart 코드에서도 초기 값을 통해 변수의 타입을 명시적으로 지정하지 않고 var를 사용하여 대부분의 변수를 선언할 수 있습니다. 타입 추론 덕분에 이러한 변수의 타입은 초기값에 의해 결정됩니다.

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'
};

Dart에서 변수에 관한 자세한 내용을 알아보려면 다음 주제를 참고하세요:

Default Values (기본값): 변수가 초기화되지 않은 경우 기본값은 무엇인가요?
Final and Const Keywords (final 및 const 키워드): final과 const 키워드는 어떻게 변수의 불변성을 나타내는 데 사용되나요?
Static Types (정적 타입): Dart에서 변수의 타입을 명시적으로 지정하려면 어떻게 해야 하며, 이것이 어떤 이점을 제공하나요?
위의 주제들에 대한 자세한 정보는 Dart 공식 문서나 Dart 언어의 공식 사이트에서 찾을 수 있습니다.


제어 흐름 문장

Dart는 다음과 같은 일반적인 제어 흐름 문장을 지원합니다:

if (year >= 2001) {
  print('21st century');
} else if (year >= 1901) {
  print('20th century');
}

for (final object in flybyObjects) {
  print(object);
}

for (int month = 1; month <= 12; month++) {
  print(month);
}

while (year < 2016) {
  year += 1;
}

주어진 코드 예제에서는 Dart의 제어 흐름 문장을 보여줍니다:

if 문: 조건에 따라 다른 블록을 실행하는 조건문입니다. year 변수가 2001보다 크거나 같으면 '21세기'를 출력하고, 그렇지 않고 1901보다 크거나 같으면 '20세기'를 출력합니다.

for-in 루프: 반복 가능한 컬렉션에 대해 반복하며 flybyObjects 컬렉션의 각 요소를 출력합니다.

for 루프: 반복 횟수가 정해진 경우에 사용합니다. month 변수가 1에서 12까지 증가하면서 각 월을 출력합니다.

while 루프: 조건이 참인 동안 루프가 실행됩니다. year 변수가 2016보다 작은 경우에는 year 변수를 1씩 증가시키며 반복합니다.

이러한 제어 흐름 문장을 사용하여 코드의 실행 흐름을 제어하고 조건에 따라 다른 작업을 수행할 수 있습니다.

Dart에서 제어 흐름 문장에 대해 더 자세히 알아보려면 다음 주제를 참고하세요:

break and continue: break 문은 루프나 switch 문에서 빠져나오는 데 사용되며, continue 문은 루프에서 현재 반복을 건너뛰고 다음 반복으로 진행하는 데 사용됩니다.

switch and case: switch 문을 사용하여 여러 가지 경우를 판별하고, case 문을 사용하여 각 경우에 대한 동작을 지정합니다.

assert: assert 문을 사용하여 조건이 참이 아닐 경우 예외를 발생시키고 프로그램 실행을 중단시킬 수 있습니다. 디버깅과 코드 검증에 유용합니다.

Dart의 제어 흐름 문장에 대한 더 많은 정보는 Dart 공식 문서나 Dart 언어의 공식 사이트에서 찾을 수 있습니다.


함수

우리는 각 함수의 매개변수와 반환값의 타입을 명시하는 것을 권장합니다.

int fibonacci(int n) {
  if (n == 0 || n == 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

var result = fibonacci(20);

주어진 코드 예제는 피보나치 수열을 계산하는 함수를 정의하고, 이 함수를 사용하여 20번째 피보나치 수를 계산하는 예시를 보여줍니다.

피보나치 함수는 재귀적인 방법으로 구현되어 있으며, 주어진 n이 0 또는 1인 경우에는 n 자체를 반환하고, 그렇지 않은 경우에는 n-1과 n-2에 대한 피보나치 값을 재귀적으로 계산하여 더한 값을 반환합니다.

이 코드를 실행하면 result 변수에는 20번째 피보나치 수가 계산되어 저장됩니다.

단일 문장을 포함하는 함수에 대한 약식 => (화살표) 구문은 특히 익명 함수를 인수로 전달할 때 유용합니다.

flybyObjects.where((name) => name.contains('turn')).forEach(print);

주어진 코드는 flybyObjects라는 컬렉션에서 이름에 'turn'이 포함된 항목을 필터링하고 그 결과를 출력하는 작업을 수행합니다.

flybyObjects.where((name) => name.contains('turn')): flybyObjects 컬렉션에서 where 함수를 사용하여 조건을 만족하는 항목만 필터링합니다. 이때 조건은 이름(name)에 'turn'이 포함되어 있는지 확인하는 람다 함수로 정의됩니다.

forEach(print): 필터링된 항목에 대해 forEach 함수를 사용하여 각 항목을 print 함수로 출력합니다. 이는 필터링된 항목을 반복하면서 각 항목을 출력하는 동작을 수행합니다.

종합하면, 주어진 코드는 'turn'이라는 문자열을 포함하는 항목만을 print 함수를 사용하여 출력하는 동작을 수행합니다.

주어진 코드는 익명 함수( where() 함수에 전달되는 인수)뿐만 아니라 함수를 인수로 사용할 수 있다는 것을 보여줍니다. 최상위 함수인 print() 함수가 forEach()의 인수로 사용되었습니다.

Dart에서 함수에 대한 자세한 내용을 알아보려면 다음 주제를 참고하세요:

Optional Parameters (선택적 매개변수): 함수에서 선택적 매개변수를 선언하는 방법과 사용하는 방법에 대한 정보입니다.

Default Parameter Values (기본 매개변수 값): 함수 매개변수에 기본값을 설정하는 방법에 대한 내용입니다. 이를 사용하면 매개변수를 생략할 수 있습니다.

Lexical Scope (렉시컬 스코프): 함수 내부에서 변수의 스코프 및 접근성을 이해하는 데 도움이 되는 내용입니다.

Dart의 함수와 관련된 더 많은 정보는 Dart 공식 문서나 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에서 주석에 대한 예시를 설명해 주셨습니다. 주석은 코드를 설명하고 문서화하는 데 사용되며 다음과 같은 주석 유형이 있습니다:

//: 단일 라인 주석으로 사용되며 코드 내에서 설명을 추가하는 데 유용합니다.
///: 문서화 주석으로 사용되며 라이브러리, 클래스 및 멤버를 문서화하고 IDE 및 dartdoc과 같은 도구에서 특별하게 처리됩니다.
/* */: 여러 줄 주석으로 사용되며 여러 줄에 걸쳐 주석을 작성할 때 유용합니다.
이러한 주석을 사용하여 코드를 이해하고 문서화하는 데 도움이 됩니다.

Dart에서 주석에 대한 자세한 내용과 문서화 도구의 작동 방식에 대해 알아보려면 다음 주제를 참고하세요:

Comments in Dart (Dart에서의 주석): Dart 공식 문서에서 주석에 대한 자세한 설명과 예제를 제공합니다.

Documenting Dart Code (Dart 코드 문서화): Dart 코드를 문서화하는 방법과 dartdoc 도구를 사용하여 문서를 생성하는 방법에 대한 정보를 제공합니다.

The dartdoc Tool (dartdoc 도구): Dart 코드를 문서화하고 API 문서를 생성하는 데 사용되는 dartdoc 도구에 대한 자세한 내용을 설명합니다.

위의 주제들을 통해 Dart에서 주석과 문서화 도구의 활용 방법에 대해 더 많은 정보를 얻을 수 있습니다. Dart 코드를 더 잘 이해하고 문서화하기 위해 주석을 활용할 수 있습니다.


Imports

다른 라이브러리에서 정의된 API에 접근하려면 import를 사용합니다.

// Importing core libraries
import 'dart:math';

// Importing libraries from external packages
import 'package:test/test.dart';

// Importing files
import 'path/to/my_other_file.dart';

주석을 포함하여 주어진 코드 예제에서는 다양한 방법으로 다른 라이브러리 및 파일을 가져오는 방법을 보여줍니다. Dart에서 라이브러리 및 파일을 가져오는 방법은 다음과 같습니다:

코어 라이브러리 가져오기: 다트의 내장 코어 라이브러리를 가져올 때는 import 'dart:라이브러리이름'; 형식을 사용합니다. 예를 들어, dart:math 라이브러리를 가져오려면 import 'dart:math';을 사용합니다.

외부 패키지 라이브러리 가져오기: 외부 패키지에서 제공하는 라이브러리를 가져올 때는 패키지 이름을 포함한 경로를 사용합니다. 예를 들어, test 패키지에서 test.dart 라이브러리를 가져오려면 import 'package:test/test.dart';를 사용합니다.

파일 가져오기: 로컬 파일 시스템에서 다른 Dart 파일을 가져올 때는 파일의 경로를 사용합니다. 예를 들어, path/to/my_other_file.dart 파일을 가져오려면 import 'path/to/my_other_file.dart';를 사용합니다.

이러한 방법을 사용하여 필요한 라이브러리와 파일을 가져와서 Dart 코드에서 사용할 수 있습니다.

Dart에서 라이브러리와 가시성(visibility)에 관한 자세한 내용 및 관련 주제에 대해 알아보려면 다음 주제를 참고하세요:

Libraries in Dart (Dart에서의 라이브러리): Dart 공식 문서에서 라이브러리에 대한 개요와 사용법을 설명합니다.

Using Libraries (라이브러리 사용): 라이브러리를 가져오고 사용하는 방법을 자세히 설명합니다. 또한 라이브러리 접두사, show 및 hide 지시어에 대한 정보도 포함되어 있습니다.

Library Prefixes (라이브러리 접두사): 다른 라이브러리에서 충돌하는 식별자를 방지하기 위해 라이브러리 접두사를 사용하는 방법에 대한 내용을 다룹니다.

Show and Hide (show 및 hide): show와 hide 지시어를 사용하여 가져온 라이브러리에서 특정 요소를 선택적으로 노출하거나 숨기는 방법에 대한 설명입니다.

Lazy Loading and Deferred Loading (지연 로딩과 deferred 키워드): Dart에서 지연 로딩을 통해 라이브러리를 필요한 시점에 로드하고 사용하는 방법에 대한 정보를 제공합니다.

위의 주제를 통해 Dart에서 라이브러리와 가시성 관리에 대한 이해를 높일 수 있습니다. Dart 언어의 다양한 기능을 활용하여 모듈화된 코드를 작성하고 관리할 수 있습니다.


클래스

다음은 세 개의 속성, 두 개의 생성자 및 메서드가 있는 클래스의 예제입니다. 속성 중 하나는 직접 설정할 수 없으므로 변수 대신 getter 메서드를 사용하여 정의됩니다. 메서드는 문자열 리터럴 내에서 변수의 문자열 표현을 출력하기 위해 문자열 보간을 사용합니다.

class Spacecraft {
  String name;
  DateTime? launchDate;

  // Read-only non-final property
  int? get launchYear => launchDate?.year;

  // Constructor, with syntactic sugar for assignment to members.
  Spacecraft(this.name, this.launchDate) {
    // Initialization code goes here.
  }

  // Named constructor that forwards to the default one.
  Spacecraft.unlaunched(String name) : this(name, null);

  // Method.
  void describe() {
    print('Spacecraft: $name');
    // Type promotion doesn't work on getters.
    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라는 우주선을 나타내며, 이름(name)과 발사일(launchDate) 두 가지 속성을 가지고 있습니다. 또한 launchYear라는 읽기 전용 속성이 있으며, 이 속성은 launchDate에서 연도를 가져오는 getter 메서드를 통해 계산됩니다.

생성자는 this.name 및 this.launchDate를 통해 멤버 변수를 초기화하는 간결한 구문 설탕을 사용합니다. 또한 Spacecraft.unlaunched라는 명명된 생성자를 정의하여 미발사된 우주선 객체를 생성할 수 있습니다.

describe 메서드는 객체에 대한 정보를 출력하는 역할을 하며, 문자열 보간을 사용하여 변수의 값을 문자열 리터럴 내에서 출력합니다.

문자열과 관련된 내용을 자세히 알아보려면 Dart에서의 문자열 보간, 리터럴, 표현식 및 toString() 메서드를 다루는 다음 주제를 참고하세요:

Strings in Dart (Dart에서의 문자열): Dart 공식 문서에서 Dart에서 문자열을 사용하는 방법과 문자열 보간, 리터럴, 표현식 등에 대한 기본적인 내용을 설명합니다.

String Interpolation (문자열 보간): Dart에서 문자열 보간을 사용하여 문자열 내에서 변수나 표현식의 값을 삽입하는 방법을 설명합니다.

String Literals (문자열 리터럴): Dart에서 문자열 리터럴의 다양한 형태 및 사용법에 대한 정보를 제공합니다.

toString() Method (toString() 메서드): 클래스에서 toString() 메서드를 재정의하여 객체를 문자열로 표현하는 방법에 대한 내용을 다룹니다.

Spacecraft 클래스를 사용하는 예제와 관련된 내용은 다음과 같이 보일 수 있습니다:

var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
voyager.describe();

var voyager3 = Spacecraft.unlaunched('Voyager III');
voyager3.describe();

위의 코드 예제에서는 먼저 Spacecraft 클래스의 인스턴스를 두 개 생성하고 describe() 메서드를 호출하여 정보를 출력합니다. 코드의 실행 흐름은 다음과 같습니다:

첫 번째 줄에서 voyager라는 이름의 Spacecraft 클래스 인스턴스를 생성합니다. 이 우주선의 이름은 "Voyager I"이며 발사일은 1977년 9월 5일입니다.

voyager.describe(); 코드가 호출되면 describe() 메서드가 실행됩니다. 이 메서드는 우주선의 정보를 출력하고, launchDate가 있으면 발사일과 발사 후 경과한 시간을 출력합니다.

다음으로, unlaunched라는 이름의 미발사 우주선을 생성합니다. Spacecraft.unlaunched 명명된 생성자를 사용하여 이름만 지정하고 발사일은 null로 설정됩니다.

voyager3.describe(); 코드가 호출되면 describe() 메서드가 실행됩니다. 이 메서드는 launchDate가 null이므로 "미발사"를 출력합니다.

결과적으로 위의 코드 예제는 두 개의 우주선에 대한 정보를 생성하고 출력합니다.

Dart에서 클래스와 관련된 더 많은 내용을 자세히 알아보려면 다음 주제들을 참고하세요. 이러한 주제들은 클래스의 고급 기능과 활용법에 대한 정보를 다룹니다:

Initializer Lists (초기화자 목록): 초기화자 목록을 사용하여 클래스 생성자에서 멤버 변수를 초기화하는 방법과 관련 내용을 다룹니다.

Optional new and const (선택적 new 및 const): new와 const 키워드를 사용하여 객체를 생성하거나, 선택적으로 생략할 수 있는 방법에 대한 내용을 설명합니다.

Redirecting Constructors (리디렉팅 생성자): 생성자에서 다른 생성자로 리디렉션하는 방법에 대한 내용을 다룹니다.

Factory Constructors (팩토리 생성자): factory 생성자를 사용하여 객체 생성 프로세스를 제어하고 객체를 캐시하거나 재사용하는 방법을 설명합니다.

Getters and Setters (게터와 세터): 게터와 세터를 정의하여 클래스의 속성을 접근 및 수정하는 방법에 대한 내용을 다룹니다.

Inheritance (상속): 클래스 상속을 사용하여 새로운 클래스를 정의하고 기존 클래스의 기능을 확장하는 방법을 설명합니다.

Mixins (믹스인): 믹스인을 사용하여 다중 상속과 비슷한 기능을 활용하는 방법에 대한 정보를 제공합니다.

Interfaces and Abstract Classes (인터페이스와 추상 클래스): 추상 클래스를 사용하여 인터페이스와 유사한 기능을 구현하는 방법에 대한 내용을 다룹니다.

Class Constructors (클래스 생성자): 클래스 생성자를 사용하여 객체를 초기화하는 방법과 생성자의 다양한 형태를 설명합니다.

Class Methods (클래스 메서드): 클래스 메서드를 정의하고 사용하여 객체 생성 없이 클래스 수준의 동작을 수행하는 방법에 대한 내용을 다룹니다.

위의 주제들을 통해 Dart에서 클래스를 보다 효과적으로 활용하고 객체 지향 프로그래밍의 원칙을 따르는 방법을 학습할 수 있습니다.


Enum

열거형(Enums)은 사전에 정의된 값을 나열하거나 특정 타입의 인스턴스가 그 밖의 다른 인스턴스가 될 수 없도록 하는 방법입니다. 다음은 간단한 열거형의 예제로, 미리 정의된 행성 유형을 열거하는 방법을 보여줍니다:

enum PlanetType { terrestrial, gas, ice }

PlanetType이라는 새로운 열거형을 정의하였습니다. 이 열거형에는 세 가지 값(행성 유형)이 정의되어 있습니다:

terrestrial: 이 값은 지구와 같은 육지 행성을 나타냅니다.

gas: 이 값은 가스 행성을 나타냅니다.

ice: 이 값은 얼음 행성을 나타냅니다.

새로운 PlanetType 열거형을 사용하여 다양한 행성 유형을 나타내고 비교할 수 있습니다. 이를 통해 코드를 더 읽기 쉽고 유지보수하기 쉽게 만들 수 있습니다.

다음은 솔라 시스템의 행성들을 나타내는 클래스를 정의하는 향상된 열거형(enhanced enum)의 예제입니다. 이 예제에서는 열거형 멤버를 클래스의 상수 인스턴스로 사용하여 행성에 대한 정보를 상세하게 표현합니다:

/// Enum that enumerates the different planets in our solar system
/// and some of their properties.
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);

  /// A constant generating constructor
  const Planet(
      {required this.planetType, required this.moons, required this.hasRings});

  /// All instance variables are final
  final PlanetType planetType;
  final int moons;
  final bool hasRings;

  /// Enhanced enums support getters and other methods
  bool get isGiant =>
      planetType == PlanetType.gas || planetType == PlanetType.ice;
}

위의 코드는 Dart에서 향상된 열거형 Planet을 정의하는 예제입니다. 이 열거형은 우리 태양계의 행성들을 나열하고 각 행성의 속성을 정의합니다.

주요 요소와 설명은 다음과 같습니다:

Planet 열거형: 여러 행성을 정의합니다.
각 행성은 해당하는 행성 유형(planetType), 달의 개수(moons), 그리고 반지 여부(hasRings)와 함께 정의됩니다.
Planet 열거형은 const 생성자를 사용하여 생성됩니다. 이 생성자는 행성의 속성을 인자로 받습니다.
각 행성의 속성(planetType, moons, hasRings)은 final로 선언되어 변경할 수 없습니다.
isGiant 게터 메서드는 열거형 멤버에 대한 추가 정보를 제공하며, 행성이 거대한 행성인지 여부를 반환합니다.
이러한 열거형을 사용하면 행성들을 구조화된 방식으로 나열하고 속성을 쉽게 접근할 수 있습니다. 각 행성은 해당 속성과 연결되어 있으며, 코드의 가독성을 향상시킵니다.

Planet 열거형을 다음과 같이 쓸 수도 있습니다:

final yourPlanet = Planet.earth;

if (!yourPlanet.isGiant) {
  print('Your planet is not a "giant planet".');
}

final yourPlanet = Planet.earth; 코드는 Planet.earth를 사용하여 변수 yourPlanet를 초기화합니다. 이 변수는 현재 선택한 행성을 나타내며, 이 경우에는 지구(Planet.earth)입니다.

다음으로 if (!yourPlanet.isGiant)는 yourPlanet의 isGiant 게터를 사용하여 해당 행성이 "거대 행성"이 아닌 경우에 메시지를 출력하는 조건문입니다. ! 연산자는 논리 부정을 나타내므로, yourPlanet.isGiant가 false인 경우에 조건이 참이 됩니다.

따라서 yourPlanet가 지구인 경우에는 "Your planet is not a 'giant planet'."라는 메시지가 출력됩니다. 이것은 선택한 행성의 속성을 검사하여 특정 동작을 수행하는 데 사용된 예제입니다.

열거형(Enums)에 대한 더 자세한 정보를 얻고자 한다면 Dart의 열거형과 관련된 다음 항목들을 참고하실 수 있습니다:

Enhanced Enums: Dart 2.6부터는 열거형을 더 풍부하게 활용할 수 있는 향상된 열거형이 도입되었습니다. 이를 사용하면 열거형 멤버에 추가 정보와 메서드를 포함시킬 수 있습니다.

Automatically Introduced Properties: 열거형 멤버에는 자동으로 생성되는 index, values와 같은 속성이 있습니다. index는 열거형 내에서 멤버의 위치를 나타내며, values는 모든 멤버를 리스트로 반환합니다.

Accessing Enumerated Value Names: 열거형의 값 이름을 문자열로 얻을 수 있습니다. 예를 들어, Planet.earth.name을 통해 "earth"를 얻을 수 있습니다.

Switch Statement Support: 열거형은 switch 문과 함께 사용할 때 특히 유용합니다. 열거형 멤버를 기반으로 다양한 동작을 수행하는 데 사용할 수 있습니다.

Enhanced Enum Requirements: 향상된 열거형을 정의할 때 const 생성자와 멤버별 생성자를 구현해야 합니다. 이러한 요구 사항을 따라야 합니다.

Using Enums for Constants: 열거형은 상수 값을 나타내는 데 자주 사용됩니다. 코드 내에서 명확한 의미를 가지는 상수를 정의할 때 열거형을 활용할 수 있습니다.

이러한 기능들은 Dart에서 열거형을 더 유용하게 활용할 수 있도록 도와줍니다. Dart 열거형에 대한 자세한 내용은 Dart 공식 문서에서 확인하실 수 있습니다.

지금 다트는 3.1이다.


상속

다트는 단일 상속을 지원한다.

class Orbiter extends Spacecraft {
  double altitude;

  Orbiter(super.name, DateTime super.launchDate, this.altitude);
}

Dart에서 클래스를 확장하고 @override 주석 등을 사용하는 방법에 대해 더 자세히 알아보려면 Dart 공식 문서와 관련 리소스를 참고하실 수 있습니다. 아래는 Dart 클래스 확장과 관련된 몇 가지 중요한 주제와 관련된 링크입니다:

Extending Classes: 클래스를 확장하는 방법 및 상속에 대한 개념에 대한 정보를 얻으려면 Dart 공식 문서의 Class 섹션을 확인하세요.

@override Annotation: 부모 클래스의 메서드를 오버라이드할 때 @override 주석을 사용하는 방법에 대한 정보는 Dart 공식 문서의 The @override annotation을 참고하세요.

Superclass Constructors: 부모 클래스의 생성자를 호출하고 초기화하는 방법과 관련된 정보는 Dart 공식 문서의 Constructors 섹션을 확인하세요.

Abstract Classes: 추상 클래스를 정의하고 사용하는 방법에 대한 정보는 Dart 공식 문서의 Abstract classes 섹션을 참고하세요.

Mixin Classes: 믹스인 클래스를 사용하여 코드를 재사용하고 다중 상속과 관련된 정보는 Dart 공식 문서의 Mixins 섹션을 참고하세요.

Class Hierarchies: 클래스 계층 구조 및 다른 클래스와의 관계에 대한 정보는 Dart 공식 문서의 Class hierarchies 섹션을 확인하세요.

위의 링크를 통해 Dart 클래스 확장과 관련된 주요 주제에 대한 자세한 내용을 찾을 수 있습니다. Dart 공식 문서는 또한 다른 핵심 주제와 예제를 다루고 있으므로 관심 있는 내용을 찾아보세요.


믹스인

믹스인(Mixins)은 코드를 여러 클래스 계층 구조에서 재사용하는 방법입니다. 아래는 믹스인 선언의 예제입니다:

mixin Piloted {
  int astronauts = 1;

  void describeCrew() {
    print('Number of astronauts: $astronauts');
  }
}

Mixin의 기능을 클래스에 추가하려면 해당 클래스를 해당 믹스인과 함께 확장(extend)하면 됩니다. Dart에서 with 키워드를 사용하여 클래스에 믹스인을 적용합니다.

class PilotedCraft extends Spacecraft with Piloted {
  // ···
}

PilotedCraft 클래스에는 이제 astronauts 필드와 describeCrew() 메서드가 포함되어 있습니다.

믹스인에 대한 더 자세한 정보:

믹스인은 Dart에서 한 클래스에서 다른 클래스로 코드를 재사용하는 방법 중 하나입니다. Dart에서 믹스인을 사용하면 클래스 간의 계층 구조를 변경하지 않고도 기능을 주입할 수 있습니다. 이로써 코드의 재사용성을 향상시킬 수 있습니다.

믹스인은 새로운 기능을 클래스에 쉽게 추가하고, 다중 상속의 복잡성을 피하면서도 코드를 모듈화할 수 있는 강력한 도구입니다. Dart에서 믹스인에 대한 더 자세한 내용은 Dart 공식 문서와 관련 자료를 참고하세요.


인터페이스와 추상 클래스

모든 Dart 클래스는 암시적으로 인터페이스를 정의합니다. 따라서 어떤 클래스든 구현할 수 있습니다.

class MockSpaceship implements Spacecraft {
  // ···
}

암시적 인터페이스나 명시적 인터페이스 키워드에 대해 더 알아보세요.

추상 클래스를 생성하여 구체적인 클래스에 의해 확장(또는 구현)될 수 있습니다. 추상 클래스는 빈 본문을 가진 추상 메서드를 포함할 수 있습니다.

abstract class Describable {
  void describe();

  void describeWithEmphasis() {
    print('=========');
    describe();
    print('=========');
  }
}

제공한 코드는 Describable이라는 추상 클래스를 정의합니다. 이 클래스에는 두 개의 추상 메서드가 있습니다.

void describe(): 이 메서드는 추상 메서드로, Describable의 구체적인(추상이 아닌) 하위 클래스에서 반드시 구현되어야 합니다. 하위 클래스는 describe 메서드의 고유한 구현을 제공해야 합니다.

void describeWithEmphasis(): 이 메서드는 추상이 아니며 Describable 클래스에 기본 구현이 있습니다. 이 메서드는 등호(=)로 이루어진 줄을 출력하고 describe 메서드(이 메서드는 추상 메서드이며 하위 클래스에서 구현되어야 함)를 호출한 다음 다시 등호로 이루어진 줄을 출력합니다. 하위 클래스는 이 메서드를 재정의하여 다른 구현을 제공할 수 있습니다.

Describable를 확장하는 모든 클래스는 describeWithEmphasis() 메서드를 상속하며, 해당 클래스는 describe() 메서드를 추상 클래스인 Describable에서 필요로 하는 대로 직접 구현해야 합니다.

Dart에서의 추상 클래스와 메서드는 각 구체적인 하위 클래스가 따라야 하는 계약 또는 공통 인터페이스를 정의하는 데 사용됩니다. 이는 코드의 일관성과 구조를 유지하면서 각 하위 클래스가 독립적으로 동작을 맞춤화할 수 있도록 합니다.

Dart에서 추상 클래스와 메서드에 대해 더 자세히 알아보려면 Dart 공식 문서나 이 주제를 상세히 다루는 다른 자료를 참조하실 수 있습니다. 추상 클래스를 이해하는 것은 객체 지향 프로그래밍에서 중요한 개념 중 하나입니다.


Async

비동기 프로그래밍을 통해 콜백 지옥을 피하고 코드를 훨씬 더 가독성 있게 만들 수 있습니다.

const oneSecond = Duration(seconds: 1);
// ···
Future<void> printWithDelay(String message) async {
  await Future.delayed(oneSecond);
  print(message);
}

이 코드는 1초 동안 지연 후에 메시지를 출력하는 Dart 함수를 정의합니다. 함수의 이름은 printWithDelay이며, 지정된 메시지를 출력하기 전에 await를 사용하여 1초 동안 대기합니다.

위의 메소드는 다음과 동등합니다:

Future<void> printWithDelay(String message) {
  return Future.delayed(oneSecond).then((_) {
    print(message);
  });
}

다음 예제에서 볼 수 있듯이, async와 await를 사용하면 비동기 코드를 읽기 쉽게 만들 수 있습니다.

Future<void> createDescriptions(Iterable<String> objects) async {
  for (final 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');
    }
  }
}

이 코드는 주어진 객체 이름을 사용하여 텍스트 파일을 생성하거나 이미 존재하는 경우 파일을 업데이트하는 Dart 함수를 정의합니다. 함수는 async 키워드를 사용하여 비동기적으로 작동하며, 오류 처리를 위해 try-catch 블록을 사용합니다.

async*를 사용하면 스트림을 쉽게 구성할 수 있는 가독성 좋은 방법을 제공합니다.

Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {
  for (final object in objects) {
    await Future.delayed(oneSecond);
    yield '${craft.name} flies by $object';
  }
}

비동기 프로그래밍에 대한 자세한 내용을 학습하려면 다음 주제를 찾아보고 학습할 것을 권장합니다:

Async Functions (비동기 함수):
Dart에서 비동기 작업을 수행하는 데 사용됩니다.
async 및 await 키워드를 사용하여 코드를 보다 읽기 쉽게 만들 수 있습니다.

Future (미래):
미..래...?
Dart에서 비동기 작업의 결과를 나타내는 클래스입니다.
Future 객체는 비동기 작업이 완료될 때 결과를 처리하는 데 사용됩니다.

Stream (스트림):
이벤트 스트림을 표현하며 비동기적으로 데이터를 처리할 수 있는 방법을 제공합니다.
데이터 흐름을 모니터링하고 처리하는 데 사용됩니다.

Asynchronous Loop (비동기 루프):
await for 루프를 사용하여 스트림의 이벤트를 비동기적으로 처리할 수 있습니다.
비동기 루프를 통해 스트림에서 오는 이벤트를 계속해서 처리할 수 있습니다.

Error Handling (오류 처리):
비동기 작업 중 발생하는 오류를 처리하는 방법을 학습해야 합니다.
try-catch 블록을 사용하여 예외를 처리하고 on 키워드를 사용하여 특정 예외 유형을 처리할 수 있습니다.

Concurrency (병렬 처리):
비동기 작업을 병렬로 처리하는 방법과 작업 간의 상호작용에 대한 고려 사항을 이해해야 합니다.
Future.wait 및 Future.forEach와 같은 도구를 사용하여 병렬 작업을 관리합니다.

Best Practices (최선의 방법):
비동기 코드를 작성할 때 고려해야 할 몇 가지 최선의 방법과 패턴이 있습니다.
코드의 가독성을 유지하고 오류를 방지하기 위한 권장 사항을 따를 필요가 있습니다.

공식 Dart 언어 문서 및 Dart 공식 웹사이트에서 자세한 정보와 예제를 찾을 수 있습니다. 또한 비동기 프로그래밍에 대한 책과 튜토리얼도 참고하면 도움이 될 것입니다.


예외 처리

예외를 발생시키려면 Dart에서 throw 키워드를 사용합니다.

if (astronauts == 0) {
  throw StateError('No astronauts.');
}

주어진 코드는 astronauts 변수의 값이 0인 경우 StateError 예외를 발생시키는 예제입니다. 이 코드는 특정 상황에서 예외를 사용하여 프로그램의 동작을 제어하고 오류를 보고하는 데 사용될 수 있습니다.

예외를 잡기 위해서는 try 문과 함께 on 또는 catch (또는 둘 다)를 사용합니다. 이 두 가지 방법을 사용하여 예외를 처리하고 다른 동작을 정의할 수 있습니다.

try-on 방식 (try-on Statement):
try 문과 on 키워드를 사용하여 특정 예외 유형을 처리할 수 있습니다.
예외가 발생하면 해당 예외 유형에 매칭되는 on 블록이 실행됩니다.

try {
  // 예외를 발생시키는 코드
} on ExceptionType1 {
  // ExceptionType1 예외 처리
} on ExceptionType2 {
  // ExceptionType2 예외 처리
} catch (e) {
  // 그 외 모든 예외 처리
}

try-catch 방식 (try-catch Statement):
try 문과 catch 블록을 사용하여 예외를 처리할 수 있습니다.
catch 블록에서는 특정 예외 유형을 지정하지 않고 모든 예외를 처리합니다.

try {
  // 예외를 발생시키는 코드
} catch (e) {
  // 모든 예외 처리
}
Future<void> describeFlybyObjects(List<String> flybyObjects) async {
  try {
    for (final 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();
  }
}

주어진 Dart 코드는 비동기적으로 여러 개의 텍스트 파일을 읽어와서 출력하고, 예외가 발생한 경우 예외를 처리하고 마지막으로 flybyObjects 리스트를 비워주는 함수를 나타냅니다.

여기서 주요 구성 요소와 동작은 다음과 같습니다:

async 키워드는 이 함수가 비동기 함수임을 나타냅니다.
try 블록 내에서 flybyObjects 리스트를 반복하면서 각 객체의 텍스트 파일을 읽어옵니다.
await 키워드를 사용하여 비동기 작업이 완료될 때까지 대기합니다.
on 키워드를 사용하여 IOException 예외가 발생한 경우 예외를 처리합니다. 이 예외는 파일 읽기 동안 발생할 수 있는 문제를 나타냅니다.
finally 블록은 예외 발생 여부와 상관없이 항상 실행됩니다. 여기서는 flybyObjects 리스트를 비워주는 작업이 수행됩니다.
이 함수는 파일을 비동기적으로 읽어와서 출력하고, 파일 읽기 과정에서 예외가 발생하면 해당 예외를 처리하며, 마지막으로 flybyObjects 리스트를 비워줍니다.

주어진 코드에서 try 블록은 비동기 코드에서도 동작하는데, 이는 Dart 언어의 특징 중 하나입니다. try 블록은 동기 코드와 비동기 코드 모두에서 예외 처리에 사용될 수 있습니다.

더 많은 예외 처리 관련 주제에 대해 알아보겠습니다:

Stack Traces (스택 트레이스):
예외가 발생하면 해당 예외의 스택 트레이스(stack trace) 정보가 생성됩니다. 스택 트레이스는 예외가 발생한 곳부터 예외를 던진 경로를 추적하는 데 사용됩니다.
스택 트레이스 정보는 예외의 디버깅과 오류 식별에 도움을 줍니다.

Rethrow (재던지기):
rethrow 키워드는 현재 처리 중인 예외를 다시 던지는 데 사용됩니다. 이는 예외를 재설정하지 않고 예외를 다른 곳에서 다시 처리하려는 경우에 유용합니다.

Error vs. Exception (에러 대 예외):
Dart에서 Error와 Exception은 모두 Error 및 Exception 클래스를 상속하는 클래스입니다.
Error는 프로그램 실행 중 발생한 치명적인 오류를 나타내며, 보통 복구할 수 없는 상황에서 발생합니다.
Exception은 예외적인 상황을 나타내며, 보통 프로그램이 계속 실행될 수 있도록 예외 처리를 통해 처리됩니다. Dart에서 Exception 클래스를 직접 상속하는 사용자 정의 예외를 만들 수도 있습니다.

Custom Exceptions (사용자 정의 예외):
Dart에서는 필요한 경우 사용자 정의 예외를 생성할 수 있습니다. 이를 통해 프로그램의 특정 상황에 대한 예외를 정의하고 사용할 수 있습니다.

Catching Multiple Exceptions (다중 예외 처리):
catch 블록에서 여러 종류의 예외를 처리할 수 있습니다. 여러 예외 유형을 처리할 때 각 예외 유형에 대한 처리를 지정할 수 있습니다.

예외 처리에 관한 더 자세한 내용은 Dart 언어 문서나 예외 처리에 대한 튜토리얼을 참고하시기를 권장합니다. 이를 통해 코드의 안정성을 높이고 문제 해결을 더 쉽게 할 수 있습니다.


중요한 개념

Dart 언어를 계속 학습하면서 다음과 같은 중요한 개념과 사항을 기억하세요:

Just-in-Time (JIT) and Ahead-of-Time (AOT) Compilation:
Dart는 JIT 컴파일러와 AOT 컴파일러를 지원합니다.
JIT 컴파일러는 개발 중에 코드를 컴파일하며, 빠른 개발과 디버깅을 가능하게 합니다.
AOT 컴파일러는 미리 컴파일된 코드를 생성하여 높은 성능을 제공하며, 배포 시에 사용됩니다.

Strong Mode:
Dart는 "강한 모드"라고도 불리는 정적 타입 검사를 제공합니다.
강한 모드를 사용하면 코드의 안정성을 높일 수 있으며 타입 관련 오류를 미리 찾을 수 있습니다.

Dart Packages:
Dart 패키지 시스템을 통해 코드를 구성하고 공유할 수 있습니다.
Pub 패키지 관리자를 사용하여 패키지를 설치하고 관리합니다.

Asynchronous Programming:
Dart는 비동기 프로그래밍을 지원하며, async와 await 키워드를 사용하여 비동기 코드를 작성할 수 있습니다.
Future와 Stream을 사용하여 비동기 작업을 처리합니다.

Object-Oriented Programming (OOP):
Dart는 객체 지향 프로그래밍 언어로, 클래스와 객체를 사용하여 코드를 구성합니다.
상속, 다형성, 캡슐화와 같은 OOP 개념을 지원합니다.

Null Safety:
최신 버전의 Dart에서는 널 안전성(Null Safety)을 도입하였습니다.
널 안전성은 언어의 형식 시스템을 개선하여 널 포인터 예외를 방지합니다.

Hot Reload:
Flutter 프레임워크에서 사용되는 Dart 언어는 "핫 리로드"를 지원합니다. 이를 통해 애플리케이션을 실시간으로 수정하고 즉시 반영할 수 있습니다.

Cross-Platform Development:
Dart는 Flutter와 함께 사용되어 모바일, 웹, 데스크톱 등 다양한 플랫폼에서 애플리케이션을 개발하는 데 사용됩니다.

Garbage Collection:
Dart는 가비지 컬렉션을 사용하여 메모리 관리를 처리합니다.
개발자가 명시적으로 메모리 관리를 신경 쓰지 않아도 됩니다.

Community and Resources:
Dart 커뮤니티는 계속 성장하고 있으며, 문서, 튜토리얼, 패키지 등 다양한 리소스가 제공됩니다.
Dart에 대한 학습과 지원을 위해 온라인 커뮤니티 및 공식 문서를 활용하세요.
Dart는 다양한 플랫폼에서 애플리케이션을 개발하기 위한 강력한 언어이며, 이러한 개념과 사항을 이해하고 활용함으로써 효과적으로 Dart를 사용할 수 있습니다.


Dart에서는 모든 것이 객체이며, 모든 객체는 클래스의 인스턴스입니다. 이에 대한 주요 내용은 다음과 같습니다:

모든 것은 객체입니다: Dart에서 변수는 숫자와 문자열과 같은 간단한 데이터 유형뿐만 아니라 객체를 저장할 수 있습니다. 이것은 숫자, 함수, 심지어 null까지 객체로 취급된다는 것을 의미합니다.

객체는 클래스의 인스턴스입니다: Dart에서 모든 객체는 클래스의 인스턴스입니다. 이것은 정수(int)와 문자열(String)과 같은 기본 데이터 유형도 객체로, 관련된 메서드와 속성이 있음을 의미합니다.

Object 클래스에서 상속: Dart에서는 모든 객체가 (null 안전 모드에서 null을 제외하고) 암시적으로 Object 클래스로부터 상속받습니다. Object 클래스는 모든 Dart 객체에서 사용할 수 있는 공통 메서드와 속성을 제공합니다. 예를 들어, toString(), hashCode, ==와 같은 메서드는 Object 클래스에서 정의되어 있으므로 Dart 객체에서 사용할 수 있습니다.

Null Safety: Dart 2.12에서 도입된 Null Safety는 Dart에 추가적인 안전성을 제공하며, null 안전 모드에서만 사용할 수 있습니다. Null Safety를 사용하면 변수가 항상 null이거나 아님을 엄격하게 지정할 수 있으며, null 관련 오류를 사전에 방지할 수 있습니다.


Dart는 강력한 타입 시스템을 가지고 있지만, 타입 어노테이션은 선택 사항입니다. 이는 Dart가 타입을 추론할 수 있기 때문입니다. 예를 들어, var number = 101과 같이 변수를 선언하면 Dart는 number가 int 타입임을 추론합니다.

타입 추론은 코드의 가독성을 향상시킬 수 있으며, 코드를 더 간결하게 작성할 수 있게 도와줍니다. 그러나 필요한 경우에는 타입 어노테이션을 사용하여 변수의 타입을 명시적으로 지정할 수도 있습니다. 예를 들어:

int integerNumber = 101; // int 타입 어노테이션을 사용하여 명시적으로 정수 타입을 지정

이러한 유연성은 개발자가 코드를 작성하고 유지 관리하는 데 도움이 됩니다. Dart의 타입 추론은 안정성을 유지하면서도 코드 작성을 편리하게 만듭니다.


널 안전성이 활성화되면 변수는 명시적으로 허용하지 않는 한 null 값을 포함할 수 없습니다. 변수를 널로 만들려면 타입 뒤에 물음표(?)를 추가하면 됩니다. 예를 들어, int? 타입은 변수가 정수 또는 null 일 수 있음을 나타냅니다.

또한 Dart에서 특정 표현식이 절대 null이 아님을 알고 있지만 Dart가 그렇게 이해하지 않을 때, ! (널 어서션) 연산자를 사용하여 해당 값이 null이 아니라고 명시적으로 선언할 수 있습니다. 이 경우, 값이 null이면 예외가 발생합니다. 예를 들어, int x = nullableButNotNullInt!는 nullableButNotNullInt 변수가 널이 아님을 명시적으로 나타냅니다.

널 안전성은 코드의 안정성을 높이고 런타임에 발생할 수 있는 널 관련 오류를 사전에 방지하는 데 도움이 됩니다.


원하는 것이 어떤 타입도 허용하고자 할 때, Dart에서는 다음과 같은 옵션을 사용할 수 있습니다:

Object? (널 안전 기능 활성화된 경우): 널 안전 기능을 활성화한 경우, Object?를 사용하여 변수가 모든 비-nullable 타입 또는 null을 포함할 수 있도록 할 수 있습니다. 이것은 다양한 데이터 타입을 포함하여 nullable 타입을 고려할 때 유용합니다.

Object: 널 안전 기능이 비활성화된 경우, Object를 사용하여 변수가 모든 타입, 포함하여 nullable 타입까지 모두 허용하도록 할 수 있습니다.

특수 타입 dynamic (런타임에서 타입 확인을 미루어야 하는 경우): 필요한 경우 런타임에서 타입 확인을 미루어야 할 때 dynamic 타입을 사용할 수 있습니다. 이는 타입에 대한 엄격한 검사를 런타임으로 미루는 특별한 타입입니다.

이러한 옵션들은 코드를 더 유연하게 작성하고 다양한 타입의 데이터를 다루는 데 도움이 됩니다.


Dart는 제네릭(Generic) 타입을 지원합니다. 이를 사용하면 List< int > (정수의 목록) 또는 List< Object > (어떤 타입의 객체도 포함할 수 있는 목록)과 같이 타입 안정성을 유지하면서 다양한 타입의 데이터를 다룰 수 있습니다. 제네릭을 사용하면 코드의 재사용성을 높이고 타입 안정성을 확보할 수 있습니다.


Dart는 top-level 함수 (예: main()), 클래스 또는 객체에 연결된 함수 (정적 및 인스턴스 메서드로 각각)를 지원합니다. 또한 함수 내에서 함수를 생성할 수도 있습니다. 이러한 다양한 함수 유형을 활용하여 코드를 모듈화하고 구성할 수 있습니다. 예를 들어, top-level 함수는 프로그램의 진입점인 main() 함수와 같이 사용되며, 클래스 내부에서는 데이터와 관련된 메서드를 정의할 수 있습니다. 또한 특정 함수 내에서 다른 함수를 선언하여 코드를 조직화할 수 있습니다.


마찬가지로, Dart는 top-level 변수를 지원하며, 클래스나 객체와 관련된 변수도 지원합니다. 이러한 변수는 정적(static) 변수와 인스턴스(instance) 변수로 나뉩니다. 인스턴스 변수는 때로는 필드(fields) 또는 프로퍼티(properties)로 불릴 때도 있습니다.

Top-Level Variables: Top-level 변수는 어떤 클래스나 객체에 속하지 않는 변수로, 파일의 최상위 레벨에서 선언됩니다. 이러한 변수는 파일 어디에서든 접근 가능하며, Dart 프로그램의 다양한 부분에서 사용될 수 있습니다.

var topLevelVariable = 42;

Static Variables: 정적 변수는 클래스 레벨에서 선언되며 클래스와 관련된 변수입니다. 정적 변수는 클래스의 모든 인스턴스에서 공유되며, 클래스 이름을 통해 접근됩니다.

class MyClass {
  static var staticVariable = 10;
}

Instance Variables (Fields or Properties): 인스턴스 변수는 클래스의 인스턴스와 관련된 변수로, 클래스 내부에서 선언됩니다. 이러한 변수는 클래스의 각 인스턴스마다 별도로 존재하며, 해당 인스턴스의 상태를 나타냅니다.

class Person {
  String name; // 인스턴스 변수 (필드 또는 프로퍼티)
}

Dart는 다양한 종류의 변수를 지원하여 데이터를 저장하고 관리하는 데 유용하게 사용할 수 있습니다.


Java와는 달리 Dart는 public, protected, 그리고 private와 같은 특별한 키워드를 사용하지 않습니다. 대신에 Dart에서는 식별자가 밑줄()로 시작하면 해당 식별자는 해당 라이브러리 내에서만 접근할 수 있는 "프라이빗" 식별자로 간주됩니다. 다른 라이브러리에서는 로 시작하는 식별자에 접근할 수 없습니다.

이렇게 함으로써 Dart는 라이브러리 간의 모듈화를 지원하며, 라이브러리를 개발하고 관리하는 데 유용합니다. 따라서 _로 시작하는 식별자는 해당 라이브러리 내에서만 사용되어야 하며, 외부에서 직접 접근하지 않는 것이 좋습니다. 이것은 Dart의 라이브러리와 모듈 시스템을 보다 견고하게 만드는데 도움이 됩니다.


Dart에서는 식별자, 즉 변수 이름, 함수 이름, 클래스 이름 등은 글자 또는 언더스코어(_)로 시작할 수 있으며, 그 뒤에는 글자, 숫자, 또는 언더스코어를 자유롭게 조합할 수 있습니다. 단, 식별자는 숫자로 시작할 수 없습니다.

다음은 Dart에서 유효한 식별자의 예시입니다:

myVariable
_privateVariable
classA
_123Variable
my_function
_privateFunction

Dart의 식별자 규칙은 변수, 함수, 클래스 등의 이름을 자유롭게 정할 수 있게 하면서도 의미 있는 이름을 만들 수 있도록 해줍니다.


Dart는 표현식(expressions)과 문장(statements) 모두를 가지고 있습니다. 표현식은 런타임 값이 있는 반면, 문장은 런타임 값이 없습니다. 예를 들어, 조건 표현식인 condition ? expr1 : expr2는 expr1 또는 expr2 중 하나의 값을 가집니다. 이에 비교하여 if-else 문은 값이 없습니다. 문장은 종종 하나 이상의 표현식을 포함할 수 있지만 표현식은 직접적으로 문장을 포함할 수 없습니다.

다음은 표현식과 문장의 차이를 설명한 내용을 한글로 번역한 것입니다:

표현식 (Expressions): 표현식은 런타임에서 값을 가집니다. 예를 들어, condition ? expr1 : expr2와 같은 조건 표현식은 expr1 또는 expr2 중 하나의 값을 반환합니다. 표현식은 값 계산에 사용됩니다.

문장 (Statements): 문장은 런타임에서 값을 반환하지 않습니다. if-else 문과 같은 제어 구조 또는 함수의 정의는 문장입니다. 이러한 문장은 코드의 흐름을 제어하거나 작업을 수행하지만 값을 반환하지 않습니다.

문장과 표현식 간의 관계: 문장은 종종 하나 이상의 표현식을 포함합니다. 예를 들어, 조건문은 표현식을 평가한 결과에 따라 다른 문장을 실행합니다. 반면에 표현식은 직접적으로 문장을 포함할 수 없습니다. 표현식의 값은 다른 표현식에서 사용되거나 할당됩니다.

이러한 표현식과 문장의 개념을 이해하면 Dart 코드를 더 효과적으로 작성하고 이해하는 데 도움이 됩니다.


Dart 도구는 두 가지 종류의 문제를 보고할 수 있습니다: 경고(warnings)와 오류(errors). 경고는 단순히 코드가 제대로 작동하지 않을 수 있다는 표시일 뿐이지만, 프로그램 실행을 방해하지는 않습니다. 오류는 컴파일 시간 오류(compile-time error) 또는 실행 시간 오류(run-time error)로 나눌 수 있습니다. 컴파일 시간 오류는 코드를 전혀 실행하지 못하게 막으며, 실행 시간 오류는 코드 실행 중에 예외(exception)가 발생하는 것입니다.

경고 (Warnings): 경고는 코드가 잘못될 가능성이 있음을 알려주는 메시지입니다. 경고는 프로그램 실행을 막지 않으며, 코드가 작동할 수 있지만 예상치 못한 동작을 일으킬 수 있습니다. 경고를 주의 깊게 검토하고 수정하는 것이 좋습니다.

컴파일 시간 오류 (Compile-time Errors): 컴파일 시간 오류는 코드가 컴파일되는 동안 발생하는 오류로, 코드가 실행되지 않습니다. 컴파일러가 코드에서 심각한 문제를 발견하면 컴파일 시간 오류가 발생하며, 오류를 해결하지 않으면 프로그램은 실행되지 않습니다.

실행 시간 오류 (Run-time Errors): 실행 시간 오류는 코드가 실행되는 동안 발생하는 오류로, 예외(exception)가 발생하는 것을 의미합니다. 이러한 오류는 코드가 실행되는 동안 예상치 못한 문제가 발생할 때 발생하며, 예외 처리(exception handling)를 통해 처리될 수 있습니다.

Dart에서는 코드의 안정성을 높이고 오류를 사전에 감지하기 위해 경고와 오류를 주의 깊게 다루는 것이 중요합니다.


추가 리소스

Dart 학습 및 개발을 더욱 효과적으로 수행하기 위해 다음 리소스를 활용할 수 있습니다:

라이브러리 투어 (Library Tour): 라이브러리 투어는 다양한 Dart 라이브러리 및 기능에 대한 예제와 설명을 제공합니다. Dart 언어 및 라이브러리에 대한 실용적인 정보를 얻을 수 있는 좋은 출발점입니다.

Dart API 참조 (Dart API Reference): Dart API 참조는 Dart 언어 및 표준 라이브러리의 API 문서를 제공합니다. 다양한 클래스, 함수 및 기능에 대한 자세한 설명과 예제 코드를 포함하고 있어 Dart 개발 중에 필요한 정보를 찾는 데 유용합니다.

Dart 스타일 가이드 (Dart Style Guide): Dart 스타일 가이드는 Dart 코드의 일관된 스타일과 규칙을 제시합니다. 코드를 작성할 때 이러한 가이드라인을 따르면 코드의 가독성과 유지 관리가 향상되며, Dart 커뮤니티와의 협업이 원활해집니다.

이러한 리소스를 활용하여 Dart 언어와 라이브러리를 더 깊이 이해하고 효과적으로 활용할 수 있을 것입니다. Dart 개발을 위한 학습과 실무에서의 적용을 지원하는데 도움이 됩니다.


끝!

profile
여기는 일상 블로그, 기술 블로그는 https://yourhealingcoder.tistory.com/

0개의 댓글