반응형

Dart의 조건문은 프로그램의 흐름을 제어하고 특정 조건에 따라 다른 코드를 실행하는 데 사용됩니다.

주요 조건문에는 if, else if, else, switch 문이 있습니다. 각 조건문과 그 사용법에 대해 설명하겠습니다.

 

1. if 문

 

if 문은 주어진 조건이 true일 때 코드를 실행합니다.

void main() {
  int number = 10;

  if (number > 5) {
    print('Number is greater than 5');
  }
}

 

2. if-else 문

 

if-else 문은 if 조건이 false일 때 else 블록의 코드를 실행합니다.

void main() {
  int number = 3;

  if (number > 5) {
    print('Number is greater than 5');
  } else {
    print('Number is not greater than 5');
  }
}

3. else if 문

 

else if 문은 여러 조건을 검사할 때 사용됩니다. 첫 번째 if 조건이 false일 때, 그 다음 else if 조건을 검사합니다.

void main() {
  int number = 7;

  if (number > 10) {
    print('Number is greater than 10');
  } else if (number > 5) {
    print('Number is greater than 5 but less than or equal to 10');
  } else {
    print('Number is 5 or less');
  }
}

4. 중첩 if 문

 

if 문은 다른 if 문 안에 중첩될 수 있습니다. 이는 복잡한 조건을 검사할 때 유용합니다.

void main() {
  int number = 8;

  if (number > 5) {
    if (number < 10) {
      print('Number is between 5 and 10');
    } else {
      print('Number is 10 or greater');
    }
  } else {
    print('Number is 5 or less');
  }
}

 

5. 삼항 연산자

 

삼항 연산자는 간단한 if-else 문을 한 줄로 표현할 수 있습니다.

void main() {
  int number = 4;
  String result = number > 5 ? 'Number is greater than 5' : 'Number is not greater than 5';
  print(result);
}

6. switch 문

 

switch 문은 하나의 변수에 대한 여러 조건을 검사할 때 사용됩니다. 각 조건은 case 키워드로 표시됩니다.

void main() {
  String grade = 'B';

  switch (grade) {
    case 'A':
      print('Excellent!');
      break;
    case 'B':
      print('Good!');
      break;
    case 'C':
      print('Fair');
      break;
    case 'D':
      print('Poor');
      break;
    default:
      print('Invalid grade');
  }
}

7. switch 문에서 fall-through 방지

 

Dart에서는 case 블록이 끝나면 break 문을 사용하여 switch 문을 종료해야 합니다. 그렇지 않으면 다음 case 블록으로 넘어가는 fall-through가 발생하지 않습니다.

void main() {
  int number = 2;

  switch (number) {
    case 1:
      print('One');
      break;
    case 2:
      print('Two');
      break;
    case 3:
      print('Three');
      break;
    default:
      print('Other number');
  }
}

요약

 

if: 조건이 참일 때 코드 실행.

if-else: 조건이 참이면 if 블록, 거짓이면 else 블록 실행.

else if: 여러 조건 검사.

중첩 if: 복잡한 조건 검사.

삼항 연산자: 간단한 if-else 문을 한 줄로 표현.

switch: 하나의 변수에 대한 여러 조건 검사.

반응형

'프론트엔드 > Flutter' 카테고리의 다른 글

flutter 리프레쉬 인디케이터  (0) 2024.07.22
dart 반복문 정리  (0) 2024.07.21
dart collection 설명 및 예시  (0) 2024.07.21
dart 연산자  (0) 2024.07.21
Dart에서 변수 초기화 null Safety 와 late 키워드  (0) 2024.07.18
반응형

Dart의 컬렉션(Collection)은 여러 요소를 관리하고 조작할 수 있는 데이터 구조를 제공합니다.

주요 컬렉션 타입으로는 리스트(List), 셋(Set), 맵(Map)이 있습니다.

각각의 컬렉션은 다양한 용도로 사용될 수 있으며, Dart는 이러한 컬렉션을 쉽게 사용할 수 있도록 다양한 메서드와 연산자를 제공합니다.

 

1. List

 

리스트(List)는 순서가 있는 요소의 집합으로, 배열과 유사합니다. 요소의 순서를 유지하며, 동일한 값을 중복해서 가질 수 있습니다.

 

생성 및 초기화

void main() {
  // 빈 리스트 생성
  List<int> numbers = [];

  // 초기값을 가지는 리스트 생성
  List<String> fruits = ['Apple', 'Banana', 'Orange'];

  // 리스트에 요소 추가
  numbers.add(1);
  numbers.add(2);
  numbers.add(3);

  // 인덱스를 사용하여 요소 접근
  print(fruits[0]); // Apple

  // 리스트 길이
  print(fruits.length); // 3
}

 

 

주요 메서드

void main() {
  List<String> fruits = ['Apple', 'Banana', 'Orange'];

  // 요소 추가
  fruits.add('Grape');

  // 여러 요소 추가
  fruits.addAll(['Mango', 'Pineapple']);

  // 요소 제거
  fruits.remove('Banana');

  // 인덱스로 요소 제거
  fruits.removeAt(1);

  // 조건에 맞는 모든 요소 제거
  fruits.removeWhere((fruit) => fruit.startsWith('A'));

  // 요소 포함 여부 확인
  print(fruits.contains('Orange')); // true

  // 요소의 인덱스 찾기
  print(fruits.indexOf('Mango')); // 2
}

 

2. Set

 

셋(Set)은 순서가 없는 고유한 요소의 집합입니다. 동일한 값을 중복해서 가질 수 없습니다.

 

생성 및 초기화

void main() {
  // 빈 셋 생성
  Set<int> numbers = {};

  // 초기값을 가지는 셋 생성
  Set<String> fruits = {'Apple', 'Banana', 'Orange'};

  // 셋에 요소 추가
  numbers.add(1);
  numbers.add(2);
  numbers.add(3);

  // 요소 추가 (중복된 요소는 추가되지 않음)
  fruits.add('Apple');

  // 셋 길이
  print(fruits.length); // 3
}

 

주요 메서드

void main() {
  Set<String> fruits = {'Apple', 'Banana', 'Orange'};

  // 요소 추가
  fruits.add('Grape');

  // 여러 요소 추가
  fruits.addAll({'Mango', 'Pineapple'});

  // 요소 제거
  fruits.remove('Banana');

  // 조건에 맞는 모든 요소 제거
  fruits.removeWhere((fruit) => fruit.startsWith('A'));

  // 요소 포함 여부 확인
  print(fruits.contains('Orange')); // true
}

 

3. Map

 

맵(Map)은 키-값 쌍으로 이루어진 컬렉션입니다. 각 키는 고유하며, 키를 통해 값에 접근할 수 있습니다.

 

생성 및 초기화

void main() {
  // 빈 맵 생성
  Map<String, int> ages = {};

  // 초기값을 가지는 맵 생성
  Map<String, int> scores = {
    'Alice': 90,
    'Bob': 85,
    'Charlie': 95,
  };

  // 맵에 요소 추가
  ages['John'] = 25;
  ages['Doe'] = 30;

  // 키를 사용하여 값 접근
  print(scores['Alice']); // 90

  // 맵 길이
  print(scores.length); // 3
}

주요 메서드

void main() {
  Map<String, int> scores = {
    'Alice': 90,
    'Bob': 85,
    'Charlie': 95,
  };

  // 요소 추가
  scores['David'] = 88;

  // 요소 제거
  scores.remove('Bob');

  // 모든 키 가져오기
  print(scores.keys); // (Alice, Charlie, David)

  // 모든 값 가져오기
  print(scores.values); // (90, 95, 88)

  // 특정 키의 값 업데이트
  scores.update('Alice', (value) => 92);

  // 키 포함 여부 확인
  print(scores.containsKey('Charlie')); // true

  // 값 포함 여부 확인
  print(scores.containsValue(88)); // true
}

결론

 

Dart의 컬렉션은 데이터를 저장하고 조작하는 데 매우 유용한 도구입니다. 리스트(List)는 순서가 있는 요소의 집합을 다루며, 셋(Set)은 고유한 요소의 집합을 다루고, 맵(Map)은 키-값 쌍을 다룹니다. 이러한 컬렉션을 사용하여 데이터를 효율적으로 관리하고 처리할 수 있습니다.

 

참고 문서

 

Dart List 클래스 문서

Dart Set 클래스 문서

Dart Map 클래스 문서

Dart Language Tour - Collections

반응형

'프론트엔드 > Flutter' 카테고리의 다른 글

dart 반복문 정리  (0) 2024.07.21
dart 조건문 정리  (0) 2024.07.21
dart 연산자  (0) 2024.07.21
Dart에서 변수 초기화 null Safety 와 late 키워드  (0) 2024.07.18
dart 3 언어 주요 변경 사항 및 새로운 기능  (0) 2024.07.18
반응형

Dart에서는 다양한 연산자를 제공하여 변수와 값에 대해 다양한 작업을 수행할 수 있습니다.

연산자는 크게 다음과 같은 범주로 나눌 수 있습니다

 

1. 산술 연산자

2. 증감 연산자

3. 관계 연산자

4. 논리 연산자

5. 비트 연산자

6. 할당 연산자

7. 조건 연산자

8. 형 변환 연산자

9. 기타 연산자

 

1. 산술 연산자

 

산술 연산자는 기본적인 산술 계산을 수행합니다.

 

+ (덧셈)

- (뺄셈)

* (곱셈)

/ (나눗셈)

~/ (몫 연산)

% (나머지 연산)

 

void main() {
  int a = 10;
  int b = 3;

  print(a + b); // 13
  print(a - b); // 7
  print(a * b); // 30
  print(a / b); // 3.3333333333333335
  print(a ~/ b); // 3
  print(a % b); // 1
}

 

2. 증감 연산자

 

증감 연산자는 변수의 값을 증가시키거나 감소시킵니다.

 

++a (전위 증가)

a++ (후위 증가)

--a (전위 감소)

a-- (후위 감소)

void main() {
  int a = 10;

  print(++a); // 11
  print(a++); // 11
  print(a); // 12
  print(--a); // 11
  print(a--); // 11
  print(a); // 10
}

 

3. 관계 연산자

 

관계 연산자는 두 피연산자 간의 관계를 비교합니다. 결과는 boolean 값입니다.

 

== (같다)

!= (같지 않다)

> (크다)

< (작다)

>= (크거나 같다)

<= (작거나 같다)

void main() {
  int a = 10;
  int b = 3;

  print(a == b); // false
  print(a != b); // true
  print(a > b); // true
  print(a < b); // false
  print(a >= b); // true
  print(a <= b); // false
}

 

4. 논리 연산자

 

논리 연산자는 boolean 값에 대해 논리 연산을 수행합니다.

 

&& (그리고)

|| (또는)

! (부정)

void main() {
  bool a = true;
  bool b = false;

  print(a && b); // false
  print(a || b); // true
  print(!a); // false
  print(!b); // true
}

 

5. 비트 연산자

 

비트 연산자는 비트 수준에서 연산을 수행합니다.

 

& (AND)

| (OR)

^ (XOR)

~ (NOT)

<< (왼쪽 시프트)

>> (오른쪽 시프트)

void main() {
  int a = 10; // 1010
  int b = 3; // 0011

  print(a & b); // 2 (0010)
  print(a | b); // 11 (1011)
  print(a ^ b); // 9 (1001)
  print(~a); // -11 (2의 보수)
  print(a << 1); // 20 (10100)
  print(a >> 1); // 5 (0101)
}

 

6. 할당 연산자

 

할당 연산자는 변수에 값을 할당하거나 특정 연산을 수행한 후 할당합니다.

 

= (할당)

+= (더한 후 할당)

-= (뺀 후 할당)

*= (곱한 후 할당)

/= (나눈 후 할당)

~/= (몫을 구한 후 할당)

%= (나머지를 구한 후 할당)

void main() {
  int a = 10;
  int b = 3;

  a += b; // a = a + b
  print(a); // 13

  a -= b; // a = a - b
  print(a); // 10

  a *= b; // a = a * b
  print(a); // 30

  a /= b; // a = a / b
  print(a); // 10.0

  a ~/= b; // a = a ~/ b
  print(a); // 3

  a %= b; // a = a % b
  print(a); // 0
}

 

7. 조건 연산자

 

조건 연산자는 특정 조건에 따라 값을 선택합니다.

 

condition ? expr1 : expr2 (삼항 연산자)

?? (널 병합 연산자)

void main() {
  int a = 10;
  int b = 3;

  var result = a > b ? 'a가 크다' : 'b가 크다';
  print(result); // a가 크다

  String? name;
  String userName = name ?? 'Guest';
  print(userName); // Guest
}

 

8. 형 변환 연산자

 

형 변환 연산자는 객체의 타입을 변환하거나 확인합니다.

 

as (형 변환)

is (타입 검사)

is! (타입 검사 - 부정)

 

void main() {
  dynamic a = 10;

  // 타입 검사
  if (a is int) {
    print('a는 int 타입입니다.');
  }

  // 타입 검사 - 부정
  if (a is! String) {
    print('a는 String 타입이 아닙니다.');
  }

  // 형 변환
  var b = a as int;
  print(b); // 10
}

 

9. 기타 연산자

 

[] (리스트 및 맵 접근 연산자)

. (멤버 접근 연산자)

?. (널 안전 멤버 접근 연산자)

.. (계단식 표기법)

void main() {
  List<int> numbers = [1, 2, 3];
  Map<String, int> ages = {'John': 25, 'Doe': 30};

  // 리스트 및 맵 접근
  print(numbers[0]); // 1
  print(ages['John']); // 25

  // 멤버 접근
  String text = 'Hello';
  print(text.length); // 5

  // 널 안전 멤버 접근
  String? nullableText;
  print(nullableText?.length); // null

  // 계단식 표기법
  var buffer = StringBuffer()
    ..write('Hello')
    ..write(' ')
    ..write('World');
  print(buffer.toString()); // Hello World
}

 

결론

 

Dart 연산자는 다양한 작업을 수행할 수 있도록 돕는 중요한 도구입니다. 연산자의 올바른 사용법을 익히면 코드의 효율성과 가독성을 높일 수 있습니다. 이 문서에서 설명한 다양한 연산자를 잘 활용하여 더욱 효과적인 Dart 프로그래밍을 수행할 수 있습니다.

 

참고 문서

 

Dart Language Tour - Operators

반응형
반응형

변수의 초기화는 변수에 값을 할당하여 사용할 준비를 하는 과정입니다.

Dart에서는 변수를 선언할 때 초기화하지 않으면 기본값이 할당되지만, 명시적으로 초기화하는 것이 좋습니다.

이는 코드의 명확성을 높이고, 런타임 오류를 방지할 수 있습니다.

 

Dart에서 변수 초기화

 

1. 기본 초기화

변수를 선언할 때 초기값을 바로 할당할 수 있습니다.

void main() {
  int number = 10;       // 정수형 변수 초기화
  double decimal = 3.14; // 실수형 변수 초기화
  String text = "Hello"; // 문자열 변수 초기화
  bool isTrue = true;    // 불리언 변수 초기화

  print(number);  // 10
  print(decimal); // 3.14
  print(text);    // Hello
  print(isTrue);  // true
}

 

2. Null Safety와 late 키워드

 

Dart의 Null Safety 기능을 사용하면 변수를 선언할 때 초기화를 강제할 수 있습니다. late 키워드를 사용하면 변수를 나중에 초기화할 수 있습니다.

void main() {
  late String description;

  description = "This is a description"; // 나중에 초기화
  print(description); // This is a description
}

 

3. final과 const

 

finalconst 키워드를 사용하면 상수 값을 초기화할 수 있습니다. final은 런타임에 초기화할 수 있지만, const는 컴파일 타임에 초기화해야 합니다.

void main() {
  final int number = 42;       // 런타임 상수
  const double pi = 3.14159;   // 컴파일 타임 상수

  print(number); // 42
  print(pi);     // 3.14159
}

4. 동적 타입 변수

 

Dart에서는 var, dynamic 키워드를 사용하여 동적 타입의 변수를 선언하고 초기화할 수 있습니다.

void main() {
  var number = 10;          // Dart가 타입을 추론 (int)
  dynamic text = "Hello";   // 동적 타입, 초기값에 따라 타입이 결정됨

  print(number); // 10
  print(text);   // Hello

  text = 42;     // dynamic 타입이므로 다른 타입의 값 할당 가능
  print(text);   // 42
}

변수 초기화의 중요성

 

1. 명확성: 변수를 선언할 때 초기값을 할당하면, 코드의 의도를 명확히 할 수 있습니다.

2. 안정성: 초기화되지 않은 변수를 사용하면 예기치 않은 오류가 발생할 수 있습니다. 초기화를 통해 이러한 오류를 방지할 수 있습니다.

3. Null Safety: Dart의 Null Safety 기능을 통해 변수를 초기화하지 않으면 컴파일 타임에 오류가 발생합니다. 이를 통해 Null 참조 오류를 방지할 수 있습니다.

 

예제: 클래스와 초기화

 

클래스의 인스턴스 변수를 초기화하는 예제입니다.

class Person {
  String name;
  int age;

  // 생성자를 통해 변수 초기화
  Person(this.name, this.age);

  // 네임드 생성자를 통해 초기화
  Person.withDefaultName(this.age) : name = 'Unknown';
}

void main() {
  var person1 = Person('John', 30);
  var person2 = Person.withDefaultName(25);

  print('${person1.name}, ${person1.age}'); // John, 30
  print('${person2.name}, ${person2.age}'); // Unknown, 25
}

 

결론

 

변수 초기화는 코드의 명확성, 안정성, Null Safety를 보장하기 위해 중요합니다. Dart에서는 다양한 방법으로 변수를 초기화할 수 있으며, final, const, late 키워드를 사용하여 다양한 초기화 시나리오를 처리할 수 있습니다. 초기화를 올바르게 사용하여 안정적이고 명확한 코드를 작성하세요.

 

1. Dart Language Tour - Variables:

이 문서는 Dart에서 변수 선언과 초기화에 대한 기본적인 개념과 사용법을 설명합니다.

Dart Language Tour - Variables

2. Dart Language Tour - Null Safety:

이 문서는 Null Safety와 관련된 개념을 다루며, 변수 초기화와 관련된 사항을 자세히 설명합니다.

Dart Language Tour - Null Safety

3. Dart Language Tour - Late Variables:

이 문서는 late 키워드를 사용하여 변수를 나중에 초기화하는 방법에 대해 설명합니다.

Dart Language Tour - Late Variables

반응형
반응형

Dart 3 버전은 다양한 개선 사항과 새로운 기능을 도입하여 개발자 경험을 향상시키고 성능을 최적화합니다. 주요 변경 사항과 새로운 기능은 다음과 같습니다:

 

주요 변경 사항 및 새로운 기능

 

1. Null Safety 강화

Null Safety는 Dart 2.12에서 도입되었지만, Dart 3에서는 더 강력한 Null Safety 기능을 제공합니다. 모든 코드가 Null Safety를 적용해야 하며, 이를 통해 Null 참조 오류를 사전에 방지할 수 있습니다.

2. Records

Dart 3에서는 새로운 데이터 구조인 Records를 도입했습니다. Records는 여러 값을 간단히 묶어 표현할 수 있는 구조로, 튜플과 유사합니다. 이는 특히 함수에서 여러 값을 반환할 때 유용합니다.

 

(int, String) recordExample() {
  return (42, "Hello");
}

void main() {
  var record = recordExample();
  print(record.$1); // 42
  print(record.$2); // Hello
}

 

 

3. Pattern Matching

Dart 3에서는 Pattern Matching을 도입하여 데이터 구조의 특정 패턴을 쉽게 매칭하고 처리할 수 있습니다. 이는 코드를 더 간결하고 명확하게 작성할 수 있게 합니다.

void main() {
  var value = (42, "Hello");
  if (value case (int number, String message)) {
    print('Number: $number, Message: $message');
  }
}

4. Enhanced Enumerations

Dart 3에서는 열거형(enumerations)에 기능을 추가하여 더 강력하게 사용할 수 있습니다. 이제 열거형에 속성과 메서드를 추가할 수 있으며, 이를 통해 더 복잡한 상태를 관리할 수 있습니다.

enum Status {
  success(200),
  notFound(404),
  serverError(500);

  final int code;

  const Status(this.code);
}

void main() {
  print(Status.success.code); // 200
}

5. Faster Compilation and Improved Performance

Dart 3는 컴파일러 성능을 향상시켜 더 빠른 빌드 시간을 제공합니다. 또한, 런타임 성능도 개선되어 애플리케이션이 더 빠르게 실행됩니다.

6. Better Interoperability with JavaScript

Dart 3는 JavaScript와의 상호 운용성을 개선하여 웹 애플리케이션 개발이 더욱 원활해졌습니다. 이를 통해 Dart 코드를 JavaScript 코드와 더 쉽게 통합할 수 있습니다.

7. Enhanced Tooling and Developer Experience

Dart 3는 개선된 도구와 개발자 경험을 제공합니다. 예를 들어, Dart 분석기와 디버거가 더 많은 기능과 향상된 성능을 제공합니다.

 

Dart 3의 주요 목표

 

안정성: Null Safety와 같은 기능을 통해 코드의 안정성을 높이고, 런타임 오류를 줄입니다.

생산성: Records, Pattern Matching, Enhanced Enumerations와 같은 기능을 통해 개발자가 더 생산적으로 코드를 작성할 수 있도록 돕습니다.

성능: 더 빠른 컴파일 시간과 향상된 런타임 성능을 제공하여 개발자와 최종 사용자 모두에게 더 나은 성능을 제공합니다.

호환성: JavaScript와의 상호 운용성을 개선하여 웹 애플리케이션 개발을 더 쉽게 만듭니다.

 

결론

 

Dart 3는 다양한 새로운 기능과 개선 사항을 도입하여 개발자 경험을 향상시키고 성능을 최적화합니다. Null Safety 강화, Records, Pattern Matching, Enhanced Enumerations, 더 빠른 컴파일과 성능 개선, JavaScript와의 상호 운용성 개선 등은 Dart 3의 주요 특징입니다. 이를 통해 Dart는 더욱 강력하고 효율적인 프로그래밍 언어가 되었습니다.

반응형
반응형

Dart 란

 

Dart는 모든 플랫폼에서 사용할 수 있는 앱을 개발하기 위해 탄생한 클라이언트 최적화된 언어

구글에서 201110월에 공개했으며 멀티 플랫폼 상에서 동작되도록 하는 앱을 개발하기 위해 디자인됨

Dart의 목표는 다양한 종류의 기기에서 동작되도록 하는 것

 

특징

기본적으로 C언어의 문법과 비슷하며 Java, C#, Javascript와 같은 구조를 갖춤

DVM(Dart VM), 네이티브 컴파일링을 통해 모바일, 데스크탑, 웹 등의 환경에서 앱 실행을 지원

Flutter라는 프레임워크의 주 언어로 사용됨

 

주요 특징

 

1. 간결하고 강력한 문법: Dart는 이해하기 쉽고 생산성을 높이는 간결한 문법을 가지고 있습니다.

2. 정적 타입 언어: Dart는 정적 타입 언어로, 컴파일 타임에 타입 검사를 수행합니다. 이를 통해 코드의 안전성을 높이고 버그를 줄일 수 있습니다.

3. 클래스 기반 객체 지향: Dart는 객체 지향 언어로, 클래스와 상속을 지원합니다.

4. 동시성 지원: asyncawait 키워드를 통해 비동기 프로그래밍을 간단하게 구현할 수 있습니다.

5. 크로스 플랫폼: Dart는 모바일, 웹, 데스크탑 등 여러 플랫폼에서 실행될 수 있습니다.

6. 빠른 컴파일 속도: Dart는 JIT(Just-In-Time) 컴파일과 AOT(Ahead-Of-Time) 컴파일을 지원하여 빠른 실행 속도를 제공합니다.

 

공식지원 IDE

안드로이드 스튜디오

인텔리제이

VS Code 

변수 선언

void main() {
  int a = 10;
  double b = 3.14;
  String name = "Dart";
  bool isActive = true;

  print(a);
  print(b);
  print(name);
  print(isActive);
}

함수 정의

void main() {
  printGreeting('John');
  int result = add(2, 3);
  print('Sum: $result');
}

void printGreeting(String name) {
  print('Hello, $name');
}

int add(int a, int b) {
  return a + b;
}

조건문과 반복문

void main() {
  int number = 5;

  if (number > 0) {
    print('Positive');
  } else if (number < 0) {
    print('Negative');
  } else {
    print('Zero');
  }

  for (int i = 0; i < 5; i++) {
    print('i: $i');
  }

  int j = 0;
  while (j < 5) {
    print('j: $j');
    j++;
  }
}

 

클래스와 객체

void main() {
  var person = Person(name: 'John', age: 30);
  person.greet();
}

class Person {
  String name;
  int age;

  Person({required this.name, required this.age});

  void greet() {
    print('Hello, my name is $name and I am $age years old.');
  }
}

 

객체 지향 프로그래밍

 

Dart는 객체 지향 프로그래밍(OOP)을 지원합니다. OOP는 코드 재사용성과 확장성을 높이는 데 도움이 됩니다. Dart에서는 클래스, 상속, 다형성, 추상화 등을 통해 OOP를 구현할 수 있습니다.

void main() {
  var dog = Dog(name: 'Buddy', age: 3);
  dog.bark();
  dog.describe();
}

class Animal {
  String name;
  int age;

  Animal({required this.name, required this.age});

  void describe() {
    print('This is $name and it is $age years old.');
  }
}

class Dog extends Animal {
  Dog({required String name, required int age}) : super(name: name, age: age);

  void bark() {
    print('Woof! Woof!');
  }
}

 

비동기 프로그래밍

 

Dart는 비동기 프로그래밍을 간단하게 구현할 수 있는 키워드인 asyncawait를 제공합니다. 이를 통해 비동기 작업을 쉽게 처리할 수 있습니다.

 

void main() async {
  print('Fetching data...');
  String data = await fetchData();
  print('Data: $data');
}

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return 'Hello from the future!';
}

 

그 외 특징

- 모든 변수는 객체이며 모든 객체는 클래스의 인스턴스임

  - 숫자, 함수, Null도 객체로 취급

- Dart 2 버전부터 Null Safety를 소개하고 있음

- Dart는 데이터 타입을 가지고 있음

- Dart는 Generic 타입을 지원

- Dart는 main()과 같은 top-level 함수를 지원

- Dart는 public, protected, private와 같은 키워드를 지원하지 않음

  - 만약 식별자 이름 앞에 언더바(_)를 붙이면 라이브러리에서 private으로 설정할 수 있음

- Dart는 삼항 연산자를 지원

 

레퍼런스

1. Dart 공식 사이트: Dart 언어의 공식 사이트로, Dart에 대한 기본적인 소개와 문서, 튜토리얼 등을 제공합니다.

Dart 공식 사이트

2. Dart 언어 투어: Dart 언어의 문법과 기능을 체계적으로 설명하는 가이드입니다.

Dart 언어 투어

3. Dart 패키지 문서: Dart 패키지 및 라이브러리에 대한 문서입니다.

Dart 패키지 문서

4. Dart API 문서: Dart의 코어 라이브러리 및 API에 대한 상세한 문서입니다.

Dart API 문서

5. Dart Null Safety 문서: Dart의 Null Safety 기능에 대한 소개와 사용 방법을 설명하는 문서입니다.

Dart Null Safety 문서

6. Dart Code Labs: Dart와 Flutter를 배우기 위한 실습형 튜토리얼입니다.

Dart Code Labs

7. Dart GitHub 리포지토리: Dart 언어의 소스 코드와 관련 자료를 확인할 수 있는 GitHub 리포지토리입니다.

Dart GitHub 리포지토리

 

반응형
반응형

BottomNavigationBar는 Flutter에서 화면 하단에 배치하여 여러 화면으로 쉽게 전환할 수 있도록 도와주는 네비게이션 바입니다.

일반적으로 3~5개의 탭을 가지며, 각 탭을 선택하면 해당 화면으로 이동할 수 있습니다.

 

주요 속성

 

items: 네비게이션 바에 표시될 항목 목록 (BottomNavigationBarItem).

currentIndex: 현재 선택된 항목의 인덱스.

onTap: 항목이 탭될 때 호출되는 콜백 함수.

type: 네비게이션 바의 유형 (fixed 또는 shifting).

backgroundColor: 네비게이션 바의 배경색.

selectedItemColor: 선택된 항목의 색상.

unselectedItemColor: 선택되지 않은 항목의 색상.

 

기본 사용 예제

 

아래는 BottomNavigationBar를 사용하여 화면 하단에 네비게이션 바를 배치하고, setState를 사용하여 화면을 업데이트하는 예제입니다.

 

코드 예제 

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  
  late TabController _tabController;
  int _selectedIndex = 0;
  
  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this);
    _tabController.addListener(
      () => setState(() => _selectedIndex = _tabController.index)
    );
  }

  // 페이지 종료 시 종료해 주는 기능
  @override
  void dispose() {
    super.dispose();

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("test title"),
        ),
        body: _selectedIndex == 0
      ? tabContainer(context, Colors.indigo, "Friends Tab")
        : _selectedIndex == 1 ? tabContainer(context, Colors.yellow, "Chats Tab")
        : tabContainer(context, Colors.blue, "Setting Tab"),
      bottomNavigationBar: SizedBox(
        height: 90,
        child: TabBar(
          controller: _tabController,
          labelColor: Colors.black,
          tabs: [
            Tab(
             icon: Icon(
                 _selectedIndex == 0 ? Icons.person : Icons.person_2_outlined
             ),
             text: "Friends",
            ),
            Tab(
              icon: Icon(
                  _selectedIndex == 1 ? Icons.chat : Icons.chat_outlined
              ),
              text: "Chats",
            ),
            Tab(
              icon: Icon(
                  _selectedIndex == 2 ? Icons.settings : Icons.settings_outlined
              ),
              text: "Settings",
            ),
          ],
        ),
      ),
    );
  }

  Widget tabContainer(BuildContext con, Color tabColor, String tabText) {
    return Container(
      width: MediaQuery.of(con).size.width,
      height: MediaQuery.of(con).size.height,
      color: tabColor,
      child: Center(
        child: Text(
          tabText,
          style: const TextStyle(
            color: Colors.white
          ),
        ),
      ),
    );
  }

}

 

 

다른 예제 

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _selectedIndex = 0;

  static const List<Widget> _widgetOptions = <Widget>[
    Text(
      'Home Page',
      style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
    ),
    Text(
      'Search Page',
      style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
    ),
    Text(
      'Profile Page',
      style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
    ),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('BottomNavigationBar Example'),
      ),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            label: 'Search',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: 'Profile',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}

 

주요 포인트

 

1. BottomNavigationBarItem: 네비게이션 바에 표시될 항목을 정의합니다. iconlabel 속성을 가집니다.

2. currentIndex: 현재 선택된 항목의 인덱스를 저장합니다.

3. onTap: 항목이 탭될 때 호출되는 콜백 함수로, 선택된 인덱스를 업데이트하고 화면을 새로 고칩니다.

4. setState: 상태 변화를 적용하여 UI를 다시 빌드합니다.

 

BottomNavigationBar와 setState 설명

 

BottomNavigationBar

 

BottomNavigationBar는 하단 네비게이션 바를 만드는 데 사용됩니다. 여러 개의 탭을 제공하여 각 탭에 다른 화면을 연결할 수 있습니다.

 

items: BottomNavigationBarItem 목록으로, 각 항목에는 iconlabel이 포함됩니다.

currentIndex: 현재 선택된 탭의 인덱스를 지정합니다.

onTap: 탭이 선택될 때 호출되는 콜백 함수로, 탭의 인덱스를 매개변수로 받습니다.

 

setState

 

setState는 상태가 변경될 때 UI를 다시 빌드하는 데 사용됩니다. 네비게이션 바의 선택된 인덱스를 업데이트할 때 호출됩니다.

 

setState(): 내부 상태를 업데이트하고 변경된 상태를 반영하기 위해 UI를 다시 빌드합니다. 상태 변경이 필요할 때마다 호출해야 합니다.

 

요약

 

BottomNavigationBar는 Flutter에서 화면 하단에 네비게이션 바를 배치하여 여러 화면으로 쉽게 전환할 수 있도록 도와줍니다.

setState는 상태 변경 시 UI를 다시 빌드하는 데 사용됩니다.

BottomNavigationBarsetState를 함께 사용하여 탭 선택 시 화면을 업데이트할 수 있습니다.

반응형
반응형

sharedPreferences는 Flutter에서 간단한 키-값 쌍을 영구적으로 저장하는 데 사용되는 패키지입니다.

이 패키지는 Android의 SharedPreferences와 iOS의 NSUserDefaults를 래핑합니다.

작은 데이터를 영구적으로 저장하고자 할 때 유용합니다.

 

주요 기능

 

데이터 저장: 문자열, 정수, 부울, 더블 등의 간단한 데이터를 저장할 수 있습니다.

데이터 읽기: 저장된 데이터를 읽어올 수 있습니다.

데이터 삭제: 특정 키에 해당하는 데이터를 삭제할 수 있습니다.

모든 데이터 삭제: 모든 데이터를 삭제할 수 있습니다.

 

1. 패키지 추가

 

pubspec.yaml 파일에 shared_preferences 패키지를 추가합니다.

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.0.6

 

2. 패키지 가져오기

 

Dart 파일에서 shared_preferences 패키지를 가져옵니다.

import 'package:shared_preferences/shared_preferences.dart';

 

3. 데이터 저장

 

데이터를 저장하는 예제입니다.

Future<void> saveData() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString('username', 'John Doe');
  await prefs.setInt('age', 30);
  await prefs.setBool('isLoggedIn', true);
  await prefs.setDouble('height', 1.75);
}

4. 데이터 읽기

 

저장된 데이터를 읽어오는 예제입니다.

Future<void> readData() async {
  final prefs = await SharedPreferences.getInstance();
  String? username = prefs.getString('username');
  int? age = prefs.getInt('age');
  bool? isLoggedIn = prefs.getBool('isLoggedIn');
  double? height = prefs.getDouble('height');

  print('Username: $username');
  print('Age: $age');
  print('Is Logged In: $isLoggedIn');
  print('Height: $height');
}

 

5. 데이터 삭제

 

특정 키에 해당하는 데이터를 삭제하는 예제입니다.

Future<void> removeData() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.remove('username');
}

6. 모든 데이터 삭제

 

모든 데이터를 삭제하는 예제입니다.

Future<void> clearData() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.clear();
}



예시 

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  late SharedPreferences _prefs;
  String _username = "";
  final TextEditingController _userController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _getUsername();
  }

  _saveUsername() {
    setState(() {
      _username = _userController.text;
      _prefs.setString("currentUsername", _username);
    });
  }

  _getUsername() async {
    _prefs = await SharedPreferences.getInstance();
    setState(() {
      _username = _prefs.getString("currentUsername") ?? "";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("test title"),
        ),
        body: Container(
          child: Column(
            children: [
              Text("현재 사용자 이름 : $_username" ),
              Container(
                child: TextField(
                  controller: _userController,
                  textAlign: TextAlign.left,
                  decoration: const InputDecoration(
                    border: InputBorder.none,
                    hintText: 'Input your username'
                  ),
                ),
              ),
              TextButton(
                  onPressed: () => _saveUsername()
                  , child: Text('저장')
              )
            ],
          ),
        )

    );
  }
}



다른 예제 앱

 

간단한 예제 앱을 만들어 보겠습니다.

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late SharedPreferences prefs;
  String username = '';
  int age = 0;
  bool isLoggedIn = false;
  double height = 0.0;

  @override
  void initState() {
    super.initState();
    _loadData();
  }

  Future<void> _loadData() async {
    prefs = await SharedPreferences.getInstance();
    setState(() {
      username = prefs.getString('username') ?? '';
      age = prefs.getInt('age') ?? 0;
      isLoggedIn = prefs.getBool('isLoggedIn') ?? false;
      height = prefs.getDouble('height') ?? 0.0;
    });
  }

  Future<void> _saveData() async {
    await prefs.setString('username', 'John Doe');
    await prefs.setInt('age', 30);
    await prefs.setBool('isLoggedIn', true);
    await prefs.setDouble('height', 1.75);
    _loadData();
  }

  Future<void> _removeData() async {
    await prefs.remove('username');
    _loadData();
  }

  Future<void> _clearData() async {
    await prefs.clear();
    _loadData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SharedPreferences Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('Username: $username'),
            Text('Age: $age'),
            Text('Is Logged In: $isLoggedIn'),
            Text('Height: $height'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _saveData,
              child: Text('Save Data'),
            ),
            ElevatedButton(
              onPressed: _removeData,
              child: Text('Remove Username'),
            ),
            ElevatedButton(
              onPressed: _clearData,
              child: Text('Clear All Data'),
            ),
          ],
        ),
      ),
    );
  }
}

 

주요 포인트

 

SharedPreferences: 간단한 키-값 쌍을 영구적으로 저장하는 데 사용됩니다.

getInstance(): SharedPreferences의 인스턴스를 얻기 위해 사용됩니다.

setString, setInt, setBool, setDouble: 데이터를 저장하는 메서드입니다.

getString, getInt, getBool, getDouble: 데이터를 읽어오는 메서드입니다.

remove: 특정 키에 해당하는 데이터를 삭제하는 메서드입니다.

clear: 모든 데이터를 삭제하는 메서드입니다.

 

SharedPreferences 문서

 

SharedPreferences 패키지 문서

 

 

반응형

+ Recent posts