[Dart] Equatable 리스트의 연결 방법은 +

abstract class SleepTimeState extends Equatable {
  const SleepTimeState();

  final DateTime timestamp = DateTime.now(); // 공통 속성

  @override
  List<Object> get props => [timestamp]; // 공통적으로 비교할 속성
}

final class SleepTimeCalcFailure extends SleepTimeState {
  const SleepTimeCalcFailure(this.ex);

  final Exception ex;

  @override
  List<Object> get props => super.props + [ex]; // 부모의 props에 덧붙이기
}

리스트 연결을 +가 아니라 리스트 내에 , 형태로 추가해도 될까요?

super.props + [ex]처럼 사용하는 것은 리스트의 연결 방식이기 때문에 가능합니다. super.props는 이미 리스트 형태이므로, 다른 리스트 [ex]와 연결할 수 있답니다.

반면에, + [super.props, ex]처럼 사용하면 안 되는 이유는 super.props 자체가 리스트이기 때문에 중첩된 리스트(List of List)가 생성되기 때문입니다. Flutter의 Equatable은 중첩된 리스트를 제대로 처리하지 않으므로, 의도한 대로 동작하지 않을 가능성이 높습니다.

차이

  1. super.props + [ex]:super.props는 리스트이고, [ex] 역시 리스트입니다. 리스트끼리 + 연산자를 사용하면 두 리스트가 연결되어 새로운 리스트가 됩니다. 예를 들어, super.props[a, b]라면 super.props + [ex][a, b, ex]가 됩니다. 이렇게 하면 Equatablea, b, ex를 각각 비교하게 됩니다.
    @override
    List<Object> get props => super.props + [ex];
    
    이 코드의 동작:
    • super.props에서 반환된 리스트 ([a, b])에 [ex]를 연결해서 하나의 리스트 [a, b, ex]를 만들고, 이를 props로 반환합니다.
    • 이 방식은 정상적으로 동작하며, Equatable이 이 리스트의 요소들을 하나하나 비교할 수 있습니다.
  2. [super.props, ex]:이 경우, super.props 자체가 리스트이기 때문에 props에서 중첩된 리스트가 생깁니다. 즉, super.props[a, b]라면 [super.props, ex][[a, b], ex]가 됩니다. 이는 중첩된 리스트를 생성하게 되어, Equatable이 제대로 동등성을 비교하지 못합니다.
    @override
    List<Object> get props => [super.props, ex];  // 잘못된 방식
    
    이 코드의 문제:
    • super.props가 리스트이기 때문에 props[[a, b], ex]라는 중첩 리스트를 반환합니다.
    • 이 경우 Equatable이 리스트를 제대로 비교하지 못하고, 비교 결과가 기대와 다를 수 있습니다.

테스트

다음과 같이 테스트할 수 있습니다.
abstract class ParentClass extends Equatable {
  final int a;
  final int b;

  const ParentClass(this.a, this.b);

  @override
  List<Object> get props => [a, b];
}

final class ChildClass extends ParentClass {
  final String ex;

  const ChildClass(int a, int b, this.ex) : super(a, b);

  // List<Object> get props => super.props + [ex];  // 올바른 방식
  @override
  List<Object> get props => [super.props, ex];  // 잘못된 방식
}

void main() {
  final child1 = ChildClass(1, 2, "error");
  final child2 = ChildClass(1, 2, "error");

  print(child1 == child2);  // false (잘못된 방식으로 인해)
}
위 코드에서 child1 == child2의 결과는 false가 됩니다. 이는 props[[1, 2], "error"]와 같이 중첩된 리스트를 비교하려고 하기 때문에 발생하는 문제입니다.

결론:

  • super.props + [ex]: 이 방식은 리스트를 연결하여 동등성 비교가 정상적으로 이루어집니다.
  • [super.props, ex]: 이 방식은 중첩 리스트를 만들어 의도와 다르게 동작하므로 피해야 합니다.

Equatable은 리스트의 모든 요소를 하나의 리스트로 만들어야 올바르게 비교를 수행합니다.

이전최근
댓글 쓰기
가져가실 때, 출처 표시 부탁드려요! 감사합니다. 💗