티스토리 뷰

반응형

플러터는 다트 언어를 사용한다. 다트의 객체에 동등성에 대해서 알아보자.

 

 

 

예제 코드

Person 클래스를 구현하였다. 그리고 동일한 속성을 가지는 두 객체를 생성한 후 == 연산자로 동등성을 확인하였더니 false가 나왔다.

class Person {
  String name;
  int age;

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

void main() {
  var a = Person('John', 26);
  var b = Person('John', 26);
  
  print(a == b);  // false
}

 

 

 

다트의 == 연산자

다트에서 == 연산자는 두 객체의 동등성을 비교하는 데 사용된다. == 연산자의 작동 방식은 객체의 주소(메모리 위치)를 기반으로 한다.즉, 두 객체가 정확히 같은 인스턴스인 경우에만 true를 반환한다.

 

그래서 다음 코드는 동일한 속성을 가지는 Person 객체를 생성해도 같은 객체가 아니므로 == 연산자로 비교시 false가 된다. 

class Person {
  String name;
  int age;

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


void main() {
  var a = Person('John', 26);
  var b = Person('John', 26);
  
  print(a == b);  // false
}

 

 

 

사용자 동등성 구현하기

결국 다트의 == 연산자는 동일한 객체인지를 확인하는 동등성이 된다. 하지만 코드를 작성하다보면 속성이 같은지를 확인하는 동등성이 필요한 경우가 많다. 따라서 여기서는 속성이 같은지를 확인하는 동등성을 구현해보도록 하자.

 

동등성을 구현하기 위해서는 == 연산자를 오버라이드하면 된다. 그리고 hashCode를 오버라이드해야 한다. 이 규칙은 다트2.0부터 적용된 규칙이므로 따르도록 하자. 

 

== 연산자 오버라이드는 두 객체가 동등한지 비교해서 결과를 불리언으로 리턴되게 하면 된다. hashCode 오버라이드는 동등한 객체들은 동일한 동일한 int 값이 리턴되게 하면 된다. 오버라이드의 구현은 정답이 없다. 

 

나는 Person의 == 연산자 오버라이드를 다음같이 구현하였다.

1. identical()로 두 객체가 동일한지 확인한다.

2. 두 객체가 같은 타입이고, name과 age 속성이 같은지 확인한다. 

 

hashCode 오버라이드는 name의 hashCode와 age의 hashCode를 XOR로 구현하였다.

class Person {
  String name;
  int age;

  Person(this.name, this.age);

  // == 연산자 오버라이드
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is Person && this.name == other.name && this.age == other.age;
  }

  // hashCode 오버라이드
  int get hashCode => name.hashCode ^ age.hashCode;
}

 

 

 

equatable 패키지를 사용하는 방법

== 연산자와 hashCode를 직접 구현해서 동등성을 구현할 수도 있지만, 매번 클래스에 직접 동등성을 구현하는 것은 귀찮을 수 있다. 그래서 equatable 패키지를 사용하면 더 쉽게 이를 구현할 수 있다.

 

먼저 pubspec.yaml에 equatable를 추가한다.

dependencies:
  equatable: ^2.0.0

 

동등성을 추가할 클래스에 Equatable를 확장하고, 동등성에서 사용할 속성을 props getter로 구현한다.

 

다음 코드는 Person 클래스에 Equatable를 확장하고 name과 age를 props getter로 구현한 코드가 된다.

import 'package:equatable/equatable.dart';

class Person extends Equatable {
  const Person(this.name, this.age);

  final String name;
  final int age;

  @override
  List<Object> get props => [name, age];
}
반응형
댓글
공지사항