본문 바로가기
Dart/Dart Programming language

[고급] Dart제네릭 프로그래밍/ 제네릭 클래스와 함수 작성 방법 - 단계별 예제와 설명

by Maccrey Coding 2024. 9. 8.
반응형

 

 

Dart는 타입 안전성과 코드 재사용성을 제공하는 강력한 언어로, 제네릭(Generic)은 이러한 이점을 극대화할 수 있는 중요한 기능입니다. 이번 글에서는 제네릭 클래스를 작성하고 제네릭 함수를 만드는 방법에 대해 설명하겠습니다.

초보자도 이해하기 쉽게 단계별로 설명할 테니, 끝까지 따라와 보세요!

1. 제네릭 클래스 작성하기

제네릭 클래스는 클래스 내부에서 다양한 타입을 처리할 수 있도록 하는 구조입니다. 제네릭 클래스를 사용하면 동일한 로직을 여러 타입에 적용할 수 있어 코드 재사용성을 높일 수 있습니다.

1.1 기본 구조

제네릭 클래스는 다음과 같은 기본 구조를 가집니다.

class ClassName<T> {
  T value;

  ClassName(this.value);

  void showValue() {
    print(value);
  }
}

위 코드에서 T는 타입 파라미터로, 클래스가 어떤 타입이든 유연하게 처리할 수 있게 해줍니다.

1.2 예제: 제네릭 박스 클래스

아래 예제에서는 Box라는 제네릭 클래스를 만들어 봅니다.

이 클래스는 value라는 변수를 가지고 있으며, 이는 어떤 타입이든 될 수 있습니다.

class Box<T> {
  T value;

  Box(this.value);

  void display() {
    print('Box contains: $value');
  }
}

void main() {
  Box<int> intBox = Box(100);
  Box<String> stringBox = Box("Dart");

  intBox.display(); // 출력: Box contains: 100
  stringBox.display(); // 출력: Box contains: Dart
}

설명

  • Box<int>는 정수형 값을 저장하는 박스를 의미합니다.
  • Box<String>은 문자열을 저장하는 박스를 의미합니다.
  • display() 메서드를 통해 박스 안의 값을 출력할 수 있습니다.

2. 제네릭 함수 작성하기

제네릭 함수는 함수가 다양한 타입을 처리할 수 있도록 해줍니다. 특정 타입에 종속되지 않고, 호출 시 전달된 타입에 따라 동작할 수 있습니다.

2.1 기본 구조

제네릭 함수는 함수 이름 앞에 타입 파라미터를 지정하여 작성합니다.

T functionName<T>(T param) {
  // 함수 로직
  return param;
}

위 구조에서 T는 함수가 어떤 타입을 처리할지 결정하게 합니다.

2.2 예제: 제네릭 더하기 함수

아래는 두 개의 숫자를 더하는 제네릭 함수를 예시로 들어보겠습니다.

T add<T extends num>(T a, T b) {
  return a + b;
}

void main() {
  print(add(10, 20)); // 출력: 30
  print(add(1.5, 2.5)); // 출력: 4.0
}

설명

  • T extends num은 T가 반드시 숫자 타입(int, double 등)이어야 한다는 제약 조건입니다.
  • add() 함수는 숫자 타입에 관계없이 두 개의 값을 더해줍니다.

2.3 예제: 제네릭 리스트 필터 함수

다음은 리스트에서 특정 조건을 만족하는 요소들만 필터링하는 제네릭 함수를 작성해 봅니다.

List<T> filter<T>(List<T> items, bool Function(T) predicate) {
  List<T> result = [];
  for (var item in items) {
    if (predicate(item)) {
      result.add(item);
    }
  }
  return result;
}

void main() {
  List<int> numbers = [1, 2, 3, 4, 5];
  List<int> evenNumbers = filter(numbers, (n) => n % 2 == 0);
  print(evenNumbers); // 출력: [2, 4]
}

설명

  • filter() 함수는 리스트와 조건(predicate)을 받아 해당 조건을 만족하는 요소들만 반환합니다.
  • List<T>는 반환되는 리스트가 원래 리스트와 동일한 타입임을 보장합니다.

3. 제네릭 클래스와 함수 활용 팁

  • 타입 제약 조건 사용: 제네릭에 타입 제약 조건을 걸면 예상치 못한 타입이 사용되는 것을 방지할 수 있습니다. 예를 들어, T extends num처럼 특정 타입만 허용할 수 있습니다.

  • 다중 타입 파라미터 사용: 제네릭 클래스나 함수에서 여러 개의 타입 파라미터를 사용할 수 있습니다. 예를 들어 Map<K, V>처럼 두 개의 타입을 사용하는 것이 가능합니다.

  • 명확한 타입 지정: 제네릭을 사용할 때는 가능한 한 타입을 명확하게 지정하는 것이 좋습니다. 이렇게 하면 컴파일 타임에 타입 오류를 쉽게 잡아낼 수 있습니다.

Dart에서 제네릭 클래스와 함수를 사용하면 다양한 타입에 대해 동일한 코드를 재사용할 수 있어 매우 유용합니다.

제네릭을 통해 코드의 유연성과 안정성을 높이고, 실수를 줄일 수 있습니다.

이번 포스트에서 다룬 제네릭의 개념과 활용 방법을 잘 이해하고 실제 프로젝트에서 활용해 보세요. 개발의 재미와 생산성이 모두 높아질 것입니다!

구독!! 공감과 댓글은 저에게 큰 힘이 됩니다.

Starting Google Play App Distribution! "Tester Share" for Recruiting 20 Testers for a Closed Test.

 

Tester Share [테스터쉐어] - Google Play 앱

Tester Share로 Google Play 앱 등록을 단순화하세요.

play.google.com

 

 

반응형