본문 바로가기
Flutter

플러터에서 Generics 쉽게 이해하기

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

 

Generics(제네릭)는 특정 타입에 구애받지 않고 다양한 데이터를 처리할 수 있도록 하는 기능입니다.

제네릭을 사용하면 코드의 재사용성이 높아지고, 타입 안정성이 보장됩니다.

Flutter에서는 제네릭을 사용하여 다양한 위젯이나 데이터 구조를 더 유연하게 설계할 수 있습니다.

1. Generics란?

Generics는 다양한 데이터 타입을 다룰 수 있는 일반적인 코드 구조를 의미합니다.

예를 들어, Dart의 List 클래스는 제네릭을 사용하여 숫자, 문자열, 위젯 등 모든 타입의 데이터를 담을 수 있습니다.

예시: 리스트(List)

List<int> numbers = [1, 2, 3]; // 정수 리스트
List<String> words = ["hello", "world"]; // 문자열 리스트
List<Widget> widgets = [Text("Hello"), Text("World")]; // 위젯 리스트

위 예시에서 List<int>는 정수만, List<String>은 문자열만, List<Widget>은 Flutter 위젯만 담을 수 있는 리스트입니다.

이처럼 제네릭을 사용하면 리스트가 담을 수 있는 데이터의 타입을 유연하게 지정할 수 있습니다.

2. 제네릭 클래스 만들기

Flutter에서도 제네릭 클래스를 활용할 수 있습니다.

제네릭 클래스를 사용하면 하나의 클래스가 여러 데이터 타입을 처리할 수 있어, 코드 재사용성이 높아집니다.

예시: 제네릭 클래스

class Storage<T> {
  T? _item;

  void setItem(T item) {
    _item = item;
  }

  T? getItem() {
    return _item;
  }
}

void main() {
  Storage<int> intStorage = Storage<int>();
  intStorage.setItem(100);
  print(intStorage.getItem()); // 100

  Storage<String> stringStorage = Storage<String>();
  stringStorage.setItem("Hello Flutter");
  print(stringStorage.getItem()); // Hello Flutter
}

위 예시에서 Storage<T>는 제네릭 클래스로, 데이터 타입 T에 따라 다양한 타입의 데이터를 저장할 수 있습니다.

Storage<int>는 정수를 저장하고, Storage<String>은 문자열을 저장할 수 있습니다.

3. 제네릭 함수 만들기

제네릭 함수는 여러 타입의 데이터를 처리할 수 있는 함수를 의미합니다.

함수의 매개변수나 반환값의 타입을 제네릭으로 정의할 수 있습니다.

예시: 제네릭 함수

T getFirst<T>(List<T> items) {
  return items[0];
}

void main() {
  print(getFirst<int>([1, 2, 3])); // 1
  print(getFirst<String>(["apple", "banana", "cherry"])); // apple
  print(getFirst<bool>([true, false])); // true
}

위 예시에서 getFirst<T> 함수는 제네릭 타입 T를 사용하여 리스트의 첫 번째 요소를 반환합니다.

이 함수는 정수, 문자열, 불리언 등 다양한 타입의 데이터를 처리할 수 있습니다.

4. Flutter에서 제네릭 사용 예시

Flutter에서 제네릭을 사용하면 UI를 더 유연하게 만들 수 있습니다.

대표적으로 FutureBuilder 위젯은 제네릭을 사용하여 비동기 작업의 결과 타입을 지정할 수 있습니다.

예시: FutureBuilder

Future<String> fetchGreeting() async {
  await Future.delayed(Duration(seconds: 2));
  return "Hello, Flutter!";
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String>(
      future: fetchGreeting(),
      builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return CircularProgressIndicator(); // 로딩 중
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}'); // 에러 발생 시
        } else {
          return Text('Greeting: ${snapshot.data}'); // 데이터 표시
        }
      },
    );
  }
}

위 코드에서 FutureBuilder<String>은 제네릭을 사용하여 비동기 작업의 결과가 문자열(String)임을 명시합니다.

fetchGreeting() 함수는 2초 후에 "Hello, Flutter!"라는 문자열을 반환하고, 이 결과는 FutureBuilder를 통해 UI에 표시됩니다.

5. 제네릭의 장점

  • 유연성: 다양한 타입의 데이터를 처리할 수 있어, 코드 작성 시 유연하게 사용할 수 있습니다.
  • 재사용성: 제네릭 클래스를 사용하면 동일한 로직을 여러 타입에 적용할 수 있어, 코드의 재사용성이 높아집니다.
  • 타입 안전성: 컴파일 시 타입 검사를 통해 타입 안전성을 보장하여, 런타임 오류를 줄일 수 있습니다.

마치며

이번 포스트에서는 Flutter에서 Generics를 쉽게 이해할 수 있도록 설명했습니다.

제네릭은 다양한 타입의 데이터를 처리할 수 있게 해주는 강력한 도구로, Flutter 앱 개발에서 자주 사용됩니다.

제네릭을 이해하고 활용하면 코드의 유연성과 재사용성을 높일 수 있습니다.

 

 

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

 

 

반응형