소개(HelloWorld:클래스)

var command = 'CLOSED';
switch (command) {
  case 'CLOSED':
    executeClosed();
    continue nowClosed;
  // Continues executing at the nowClosed label.

  nowClosed:
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}​
void main() {
  print('Hello, World!
'); } void main(List<String> arguments) { print(arguments); }

main함수부터 시작해서 반환값이 없으면 void형이다.

인쇄 기능은 콘솔에 텍스트를 표시합니다.

main 함수는 목록을 인수로 사용할 수 있습니다.

CLI 앱을 빌드할 때 유용합니다.

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

타입을 지정하지 않아도 초기값에서 타입을 유추한다.

변수에 둘 이상의 유형이 있는 경우 Object를 유형으로 사용할 수 있습니다.

모두.

Object name="kim";
name = 12;
name = ('kim', 'lee');

기본

초기 값이 없으면 null 값이 할당됩니다.

숫자 변수도 null 값이 됩니다.

모든 값은 객체이기 때문입니다.

최상위 및 클래스 변수는 나중에 초기화됩니다.

int? age; // age에 null 값을 할당함.
print(age);


int lineCount; // non-nullable variable nul 값이 불가능함.

if (weLikeToCount) {
  lineCount = countLines();
} else {
  lineCount = 0;
}

print(lineCount);// 프린트 함수에서 사용되기 전에 할당을 했기 때문에 null이 아님.

늦은 변수

사용 가능한 조건

– 변수가 선언된 후 초기 값이 할당되는 null이 아닌 변수입니다.

– 초기 값을 변수에 늦게 할당

최신 식별자를 최상위 변수에 추가하면 오류 없이 선언 및 초기화를 수행할 수 있습니다.

late String name;

void main(){
  name="kim;
  print(name);
}

late 식별자를 적용하고 선언문과 식별자를 동시에 적용하면 late 변수를 사용할 때 값이 할당된다.

이 방법은 할당할 값이 필요하지 않고 초기화 비용이 높을 때 유용합니다.

late String name = Student(); // name이 사용되지 않으면 Student()는 실행되지 않는다.

변수 값을 변경할 계획이 없다면 final 또는 const를 사용하십시오. final은 한 번만 할당할 수 있으며 const는 컴파일 후 변경되지 않는 값입니다.

클래스에 const 변수가 있는 경우 정적 const로 표시됩니다.

값이 const인 경우에도 const를 사용할 수 있습니다.

Const 값은 재할당할 수 있지만 const 변수는 재할당할 수 없습니다.

final은 객체가 불변이지만 해당 필드의 값은 변경될 수 있음을 의미합니다.

그러나 const는 객체와 필드 값을 모두 변경할 수 없습니다.

그렇지 않으면

if (isRaining()) {
  you.bringRainCoat();
} else if (isSnowing()) {
  you.wearJacket();
} else {
  car.putTopDown();
}

for 루프

var message = StringBuffer("Dart is fun');
for (var i = 0; i < 5; i++) {
  message.write('!
'); }

안으로

for (final candidate in candidates) {
  candidate.interview();
}

모든

var collection = (1, 2, 3);
collection.forEach(print); // 1 2 3

~하는 동안

while (!
isDone()) { doSomething(); } do { printLine(); } while (!
atEndOfPage());

반복 가능/반복자

iterable은 반복자가 반복하는 연속 값 모음입니다.

Iterables에는 목록, 집합 및 지도가 포함됩니다.

iterable은 iterator.moveNext 함수를 사용하여 다음 값으로 이동할 수 있으며 현재 값은 iterator.current를 사용하여 읽을 수 있습니다.

반복 중에 iterable이 수정되면 오류가 발생합니다.

스위치 및 하우징

비교할 유형은 동일한 유형이어야 합니다.

케이스가 비어 있지 않으면 break를 사용해야 합니다.

중단을 사용하지 않은 경우 계속, 던지기 및 반환을 사용할 수도 있습니다.

var command = 'CLOSED';
switch (command) {
  case 'CLOSED':
    executeClosed();
    continue nowClosed;
  // Continues executing at the nowClosed label.

  nowClosed:
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}

주장하다

개발 중에 어설션의 값이 false인 경우 어설션을 사용하여 코드를 중단할 수 있습니다.

assert(urlString.startsWith('https'),
    'URL ($urlString) should start with "https".');

assert는 두 개의 인수를 사용합니다.

1. 부울 값, 2. 메시지. 메시지는 선택 사항입니다.

어설션은 개발 코드에서만 실행되며 배포 코드에서는 무시됩니다.

어설션을 확인하려면 dart run –enable-asserts를 실행합니다.

기능

반환 유형을 지정하지 않고 유추할 수 있지만 이렇게 하는 것이 좋습니다.

int total(){
	return 10;
 }
 
 int total() => 10;
 
 int total() => number > 5 ? 19: 11;
 int time(int? x) = > x ?? 20;
 
 int time(int x, int y){
 	return x * y;
 }

명명된 매개변수

{매개변수1, 매개변수2…}

void Hello({required String first, required String last}){
	return 'Hello $first, $last';
   }
   
int total({int x = 0, int y = 0}){
	return x + y;
  }

required를 입력하지 않거나 기본값을 입력하지 않으면 null이 할당됩니다.

명명된 매개변수와 위치 매개변수를 함께 사용할 수도 있습니다.

int total(int x, {int y = 0}){
	return x + y;
 }

선택적 위치 매개변수

String sing(String lyrics, String country, (int? time)) {
  if (time !
= null) { return '$lyrics from $country ($time)'; } return '$lyrics from $country'; }

() 안에 있으면 선택적 매개변수입니다.

기본적으로 null 값이 할당됩니다.

기본값을 지정하려면 명명된 매개변수로 입력하십시오.

주요 개체로 기능

함수는 다른 함수에 대한 인수로 입력할 수 있습니다.

변수에 기능을 할당할 수 있습니다.

void main() {
  List<String> animals = ('bird', 'snake', 'ant', 'monkey');
  for (String animal in animals) {
    shout(animal);
  }
  animals.forEach(shout);
}

void shout(String animal) {
  print('I am $animal');
}

익명 함수

이름이 없는 함수입니다.

이름이 없으므로 (){} 형태로 입력합니다.

const list = ('apples', 'bananas', 'oranges');
list.map((item) {
  return item.toUpperCase();
}).forEach((item) {
  print('$item: ${item.length}');
});//map과 forEach 함수에 이름없는 함수를 전달해주었다.

어휘 범위

렉시칼은 어휘를 의미합니다.

어휘 범위는 다른 규칙을 적용할 필요 없이 코드 레이아웃의 위치에 따라 결정되는 범위입니다.

다음 함수에서 nestedFunction의 어휘 범위에는 모든 변수가 포함됩니다.

bool topLevel = true;

void main() {
  var insideMain = true;

  void myFunction() {
    var insideFunction = true;

    void nestedFunction() {
      var insideNestedFunction = true;

    
    }
  }
}

어휘 폐쇄

폐쇄 함수가 원래 범위 밖에서 사용되는 경우에도 어휘 범위의 변수에 액세스할 수 있는 함수 개체입니다.

클로저는 범위를 벗어난 경우에도 어휘 범위 변수에 액세스할 수 있는 함수입니다.

void main() {
  Function closure = makeClosure(weather: 'December');
  print(closure('25'));
}

Function makeClosure({String weather="September"}) {
  return (String date) => '$date $weather';
}

위의 코드에서 makeClosure는 이름 없는 함수를 반환합니다.

이 이름이 없는 함수는 어휘 범위 변수 weather에 액세스할 수 있습니다.

메인 함수에서는 함수 완성 = (문자열 날짜) => ‘$date $weather’를 사용합니다.

이 시점에서 함수가 원래 범위 밖에서 사용되고 있더라도 기존 어휘 범위 변수에 액세스합니다.

이러한 함수를 클로저라고 합니다.

함수가 같은지 테스트

다른 인스턴스는 다른 방법입니다.

void foo() {} // A top-level function

class A {
  static void bar() {} // A static method
  void baz() {} // An instance method
}

void main() {
  Function x;

  // Comparing top-level functions.
  x = foo;
  assert(foo == x);

  // Comparing static methods.
  x = A.bar;
  assert(A.bar == x);

  // Comparing instance methods.
  var v = A(); // Instance #1 of A
  var w = A(); // Instance #2 of A
  var y = w;
  x = w.baz;

  // These closures refer to the same instance (#2),
  // so they're equal.
  assert(y.baz == x);

  // These closures refer to different instances,
  // so they're unequal.
  assert(v.baz !
= w.baz); }

발전기

연속된 값을 늦게 생성해야 할 때 생성됩니다.

동기 생성자는 iterable을 생성하고 비동기 생성자는 스트림을 생성합니다.

동기식 생성기를 만들려면 함수 본문에 sync*를 추가하고 yield를 사용하여 값을 저장합니다.

Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) yield k++;
}

비동기 생성기를 생성하려면 async*를 사용하십시오.

void main() {
  print("Stream (async* + yield)");
  Stream<int> sequence = countDown(3);
print("CountDown Start");
sequence.listen((int value) {
    print(value);
  });
  print("Complete");
}
Stream<int> countDown(int num) async* {
  while (num > 0) {
    yield num--;
  }
}

위 함수는 비동기 함수이므로 “CountDonw Start” 및 “Complete” 메시지가 숫자 앞에 인쇄됩니다.

생성기 함수가 재귀적이라면 yield* 를 사용하여 성능을 향상시킬 수 있습니다.

Iterable<int> naturalsDownFrom(int n) sync* {
  if (n > 0) {
    yield n;
    yield* naturalsDownFrom(n - 1);
  }
}

코멘트

한 줄 주석: //

여러 줄 주석: /* */

문서 주석: ///

수입품

통합 패키지인 경우 “dart:”라고 말하면 됩니다.

다른 라이브러리의 경우 “패키지”를 사용하십시오.

import 'dart:html';
import 'package:test/test.dart';

가져온 두 라이브러리에 동일한 이름의 식별자가 있는 경우

import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;

// Uses Element from lib1.
Element element1 = Element();

// Uses Element from lib2.
lib2.Element element2 = lib2.Element();

라이브러리의 일부만 가져와서 사용하려는 경우

// Import only foo.
import 'package:lib1/lib1.dart' show foo;

// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;

라이브러리의 지연 로딩

웹 앱을 사용하면 필요에 따라 로드할 수 있습니다.

다음과 같은 경우 지연 로딩이 필요합니다.

– 웹 애플리케이션의 초기 시작 시간을 줄이고 싶은 경우

– A/B 테스트를 하고 싶은 분

– 기능을 거의 사용하지 않는 경우

처음 가져오는 경우 deferred as 를 사용해야 합니다.

import 'package:greetings/hello.dart' deferred as hello;

라이브러리를 호출하려면 loadLibrary()를 사용하십시오.

Futer<void> greet() async{
	await hello.loadLibrary();
    hello.printGreeting();
 }

loadLibrary를 여러 번 호출해도 라이브러리는 한 번만 로드되므로 여러 번 호출해도 문제가 되지 않습니다.

도서관 정책

“문서 주석” 또는 라이브러리 수준 메타데이터 주석을 지정하려면 파일 시작 부분의 라이브러리 선언에 주석을 추가합니다.