728x90

Class Fruits의 인스턴스를 생성하고 a.list 의 값을 확인해보자.

참조변수 b 에 a.list 를 할당하는 것은 shallow copy(얕은 복사)로 같은 메모리 주소를 바라보고 있어 동일한 값을 가진다.

참조변수 b에 새로운 값을 할당하고 나서 a.list 를 출력해보면 새로 추가한 수박이 반영되어 있는 걸 확인할 수 있다.

 

깊은 복사 방법은

- toList()를 추가하여 새로운 배열을 만드는 방법,

- 전개 연산자(...)를 사용하는 방법,

- map()함수를 활용하는 방법

이 있다.

class Fruits {
  List<String> _list = ['사과','복숭아','배','감','호두','자두'];
  List<String> get list => _list;
}
 
void main(){
  final a = Fruits();
  print(a.list); // [사과, 복숭아, 배, 감, 호두, 자두]
  List<String> b = a.list;
  print(b);      // [사과, 복숭아, 배, 감, 호두, 자두]
  print(a.list == b); // true 얕은 복사(동일한 메모리 주소를 가짐)
 
  b.add('수박');
  print(a.list); // [사과, 복숭아, 배, 감, 호두, 자두, 수박]
 
  List<String> c = a.list.toList(); // 새로운 배열
  print(c == a.list); // fasle 깊은 복사(deep copy)
  print(c); // [사과, 복숭아, 배, 감, 호두, 자두, 수박]
  /***
   * 깊은 복사란, 값이 동일한 객체를 새롭게 생성하는 것을 의미한다.
   */
 
  List<String> d = [...a.list]; // 전개 연산자를 활용하여 새로운 배열
  print(d == a.list); // false 깊은 복사
  print(d); // [사과, 복숭아, 배, 감, 호두, 자두, 수박]
 
  List<String> e = a.list.map((e) => e).toList();
  // map은 배열을 순환하며 값을 변경할 수 있는 함수이다.
  // map()은 Iterable을 반환한다.
  print('-------------------------------');
  print(e); // [사과, 복숭아, 배, 감, 호두, 자두, 수박]
  print(e == a.list); // false. 깊은 복사
 
  c.add('살구');
  print(c);      // [사과, 복숭아, 배, 감, 호두, 자두, 수박, 살구]
  print(a.list); // [사과, 복숭아, 배, 감, 호두, 자두, 수박]
 
  d.add('포도');
  a.list.remove('복숭아');
  print(d);      // [사과, 복숭아, 배, 감, 호두, 자두, 수박, 포도]
  print(a.list); // [사과, 배, 감, 호두, 자두, 수박]
 
}

 

 

그리고 copyWith를 활용하는 깊은 복사 방법을 알아보자.

class Person {
  final String name;
  final int age;
 
  Person({
    required this.name,
    required this.age,
  });
 
  Person copyWith({
    String? name,
    int? age,
  }) {
    return Person(
      name: name ?? this.name,
      age: age ?? this.age,
    );
  }
 
  @override
  String toString() {
    return 'Person{name: $name, age: $age}';
  }
}
 
void main(){
  final a = Person(name: '홍길동', age: 33);
  final b = Person(name: '홍길동', age: 33);
  print(a == b); // fasle. 객체 생성할 때마다 메모리 주소가 새로 할당된다.
 
  final d = a;
  print(d == a); // true 얕은 복사(동일한 메모리 주소를 가짐)
 
  final e = a.copyWith(); // 깊은 복사
  print(a.toString()); // Person{name: 홍길동, age: 33}
  print(e.toString()); // Person{name: 홍길동, age: 33}
  print(e == a); // false. 서로 다른 메모리 주소
 
}
 

 

 

 

 

'Flutter 앱 > Dart 언어' 카테고리의 다른 글

Dart 값 비교 - Equatable 패키지  (0) 2024.01.17
Dart cascade notation  (0) 2024.01.16
Dart List.where  (0) 2024.01.16
[Dart 고급] Dart asMap, entries  (0) 2024.01.16
Dart fold 함수  (2) 2023.12.15
블로그 이미지

Link2Me

,
728x90

Operator ==

oop라는 명칭이 생겨난 이유는 모든 클래스가 기본적으로 object를 extend 하기 때문이다.
Object라는 최상위 클래스가 제공해주는 모든 파라미터들을 모든 클래스들이 사용할 수 있다는 의미다.
대부분의 언어에서는 이 Object라는 클래스에 A 인스턴스와 B 인스턴스를 비교하는 알고리즘이 정의되어 있다.
Dart 에서는 operator라는 함수에 정의 되어있고, 이를 override 함으로써 값 비교 알고리즘을 자유롭게 변경할 수 있다.


Hash Code

hashcode 함수는 Map 또는 Set에서 키의 역할을 하게 된다.
Map이나 Set은 키가 중복으로 저장될 수 없기 떄문에 Set, Map의 키로 Object가 저장되었을 때 어떻게 키값을 정의할지가 중요하다.

프로퍼티(변수)가 늘어나면 늘어날수록 operator와 hashcode를 작성하는것이 귀찮아진다.
dart에서는 equatable클래스를 상속받아 이 문제를 해결하고 있다.

Equatable 클래스를 상속받고 props 라는 메소드를 override 해주면 된다.

 

import 'package:equatable/equatable.dart';
 
class A extends Equatable {
  // Equatable 패키지는 불변 객체를 전제로 설계되었다.
  final int a;
  final int b;
 
  const A({
    required this.a,
    required this.b,
  });
 
  @override
  List<Object?> get props => [this.a, this.b];
  // Equatable 클래스를 상속을 받고
  // props 라는 메소드를 override 해주면 된다.
  // props는 비교시 사용하고 싶은 속성을 배열로 반환해주면 된다.
}
 
void main() {
  final a1 = A(a:88, b:53);
  final a2 = A(a:88, b:53);
 
  print(a1 == a2); // true
  print(a1); // A(88,53)
}
 
/***
 * Dart 기본적으로 참조 비교(Reference Equality)를 사용하기 때문에,
 * 가변 객체인 A 인스턴스는 생성할 때 마다 다른 메모리에 할당되어 false를 반환
 * Equatable 패키지를 이용하면 보다 손쉽게 값 비교를 구현할 수 있다.
 */

 

equatable 패키지 설치는 https://pub.dev/packages/equatable 를 참조하면 된다.

'Flutter 앱 > Dart 언어' 카테고리의 다른 글

Dart 얕은 복사(shallow copy), 깊은 복사(deep copy)  (0) 2024.01.17
Dart cascade notation  (0) 2024.01.16
Dart List.where  (0) 2024.01.16
[Dart 고급] Dart asMap, entries  (0) 2024.01.16
Dart fold 함수  (2) 2023.12.15
블로그 이미지

Link2Me

,