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은 중첩된 리스트를 제대로 처리하지 않으므로, 의도한 대로 동작하지 않을 가능성이 높습니다.
차이
super.props + [ex]:super.props는 리스트이고,[ex]역시 리스트입니다. 리스트끼리+연산자를 사용하면 두 리스트가 연결되어 새로운 리스트가 됩니다. 예를 들어,super.props가[a, b]라면super.props + [ex]는[a, b, ex]가 됩니다. 이렇게 하면Equatable은a,b,ex를 각각 비교하게 됩니다.
이 코드의 동작:@override List<Object> get props => super.props + [ex];super.props에서 반환된 리스트 ([a, b])에[ex]를 연결해서 하나의 리스트[a, b, ex]를 만들고, 이를props로 반환합니다.- 이 방식은 정상적으로 동작하며,
Equatable이 이 리스트의 요소들을 하나하나 비교할 수 있습니다.
[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은 리스트의 모든 요소를 하나의 리스트로 만들어야 올바르게 비교를 수행합니다.
