본문 바로가기

자료구조/자료형

[Flutter] Collection , Generic

  • Collection: 데이터들을 모아서 가지고 있는 자료구조
    List, Set, Map
  • Generic: Collection이 가지고 있는 데이터들의 데이터 타입을 지정.

 

리스트 선언시 null safety 적용으로 변경되는 사항.

 

void main() {
//var number = new List(5);
  var number = new List.filled(5,0); // 널세이프티 버전은 이렇게 코딩해야함
  
//List number2 = new List();  
  List number2 = []; // 널세이프티 버전은 이렇게 코딩해야함
  
  print(number);  //[0, 0, 0, 0, 0]
  print(number2); //[]
}

 

dynamic 키워드

 

void main() {
  // 타입을 정하지 않으면 dynamic 으로 지정된다. List<dynamic>number
  // dynamic 키워드는 변수에 여러 타입을 저장해야할 때, 사용
  List number = [];

  number.add(2);
  number.add('test');
  number.add(7.4);

  print(number); // [2, test, 7.4]
}

 

Generic

 

int addNumber(int num1, int num2) {
  return num1 + num2;
}

void main() {
  // <> 괄호가 제네릭 타입을 나타낸다
  // <>안에 리스트에 들어올 데이터의 타입을 지정
  List<dynamic> number = [];
  
  number.add(2);
  number.add('test');
  number.add(7.4);
  number.add(addNumber(3, 4));
  number.add(true);
  print(number); // [2, test, 7.4, 7, true]
}

 

Generic 을 int 로 지정한 경우, 타입 오류를 미리 막을수 있다

 

int addNumber(int num1, int num2) {
  return num1 + num2;
}

void main() {
  List<int> number = [];
  
  number.add(2);
  number.add('test'); 			// error 발생
  number.add(7.4);    			// error 발생
  number.add(addNumber(3, 4));
  number.add(true);   			// error 발생
  print(number);
}

 

Generic 타입을 지정하는 이유

 

// 제네릭 타입을 지정하는 이유는 코드의 안정성과 간결성 때문임.
void printNumber(List<int> a) {
  print(a);
}

void main() {
  // number 는 List<dynamic> 타입인데. printNumber의 인자는 List<int> 임.
  // List<int> number = List();를 사용하면 문제 없이 함수가 실행된다
  List<dynamic> number = [];
  number.add(5);
  printNumber(number); // 타입 불일치로 오류 발생
}

 

위 코드의 타입을 반대로 하면 오류가 발생하지 않는다. dynamic 타입은 모든 타입을 수용하기 때문임

 

// 제네릭 타입을 지정하는 이유는 코드의 안정성과 간결성 때문임.
void printNumber(List<dynamic> a) {
  print(a);
}

void main() {
  // number 는 List<int> 타입. printNumber의 인자는 List<dynamic> 임.
  // dynamic 타입은 모든 타입을 수용한다.
  List<int> number = [];
  number.add(5);
  printNumber(number); // [5]
}

 

Generic 스타일을 적용한 간결한 코딩예제, 각 클래스마다 insert 함수를 정의할 필요가 없음

인스턴스 생성시, Generic 타입을 지정함으로 코딩이 간결해졌다

 

// Generic 스타일 미적용시
class Circle {}
class Square {}

class CircleSlot{
  insert (Circle circleSlot){}
}

class SquareSlot{
  insert (Square squareSlot){}
}

void main() {
  var circleSlot = CircleSlot();
  circleSlot.insert(Circle());

  var squareSlot = SquareSlot();
  squareSlot.insert(Square());
}


// Generic 스타일 적용시
class Circle {}
class Square {}

class Slot<T>{
  insert (T shape){}
}

void main() {
  var circleSlot = Slot<Circle>();
  circleSlot.insert(Circle());

  var squareSlot = Slot<Square>();
  squareSlot.insert(Square());
}

 

[참고자료] 코딩셰프

[https://www.youtube.com/watch?v=6AUuEP_n38Y&list=PLQt_pzi-LLfpcRFhWMywTePfZ2aPapvyl&index=25]