Equatable 需要不可变吗

问题描述 投票:0回答:1

是否存在不遵循不可变导致错误的哈希结果的真实案例?

我做了一个测试用例来测试非不可变类,并期望它会出现错误。实际上,我们对此没有任何问题,并且 HashSet 实际上在这里工作得很好。

您能否向我们展示一个简单的真实案例场景,其中不遵循 immutable 将导致错误的 hashcode 值

import 'dart:collection';

import 'package:equatable/equatable.dart';
import 'package:flutter_test/flutter_test.dart';

class _EquatableTest extends Equatable {
  final HashSet values;

  const _EquatableTest({required this.values});

  @override
  List<Object> get props => [values];

  _EquatableTest copyWith({
    HashSet? values,
  }) {
    return _EquatableTest(
      values: values ?? this.values,
    );
  }
}

class _EquatableTestNonImmutable extends Equatable {
  HashSet values;

  _EquatableTestNonImmutable({required this.values});

  @override
  List<Object> get props => [values];
}

class _AdditionalValue extends Equatable {
  HashSet<String> letters;

  _AdditionalValue({required this.letters});

  void add(String letter) {
    letters.add(letter);
  }

  @override
  List<Object> get props => [letters];
}

void main() {
test('NonImmutable created same with _AdditionalValue value', () {
    _EquatableTest equatableImmune1;
    _EquatableTest equatableImmune2;

    equatableImmune1 = _EquatableTest(values: HashSet<_AdditionalValue>());
    equatableImmune2 = _EquatableTest(values: HashSet<_AdditionalValue>());

    equatableImmune1.values.add(_AdditionalValue(letters: HashSet.from(['a', 'b'])));
    equatableImmune1.values.add(_AdditionalValue(letters: HashSet.from(['c', 'd'])));

    equatableImmune2.values.add(_AdditionalValue(letters: HashSet.from(['a', 'b'])));
    equatableImmune2.values.add(_AdditionalValue(letters: HashSet.from(['c', 'd'])));

    expect(equatableImmune1, equatableImmune2);
  });

  test('NonImmutable changed same with _AdditionalValue value', () {
    _EquatableTest equatableImmune1;
    _EquatableTest equatableImmune2;

    equatableImmune1 = _EquatableTest(values: HashSet<_AdditionalValue>());
    equatableImmune2 = _EquatableTest(values: HashSet<_AdditionalValue>());

    _AdditionalValue value1 = _AdditionalValue(letters: HashSet<String>());
    _AdditionalValue value2 = _AdditionalValue(letters: HashSet<String>());

    value1.add('a');
    value2.add('a');

    equatableImmune1.values.add(value1);
    equatableImmune2.values.add(value2);

    expect(equatableImmune1, equatableImmune2);

    if (equatableImmune1.values.first.runtimeType == _AdditionalValue &&
        equatableImmune2.values.first.runtimeType == _AdditionalValue) {
      equatableImmune1.values.first.add('b');
      equatableImmune2.values.first.add('b');
    }

    expect(equatableImmune1, equatableImmune2);
    expect(equatableImmune1.hashCode, equatableImmune2.hashCode);
  });
}
flutter dart unit-testing hash equatable
1个回答
0
投票

是否存在不遵循不可变导致错误的哈希结果的真实案例?

一个简单的例子:

class Mutable {
  int x;

  Mutable(this.x);

  @override
  bool operator==(Object other) => other is Mutable && x == other.x;

  @override
  int get hashCode => x.hashCode;
}

void main() {
  var m = Mutable(0);

  var set = {m};
  print(set.contains(Mutable(0))); // Prints: true

  m.x = 1;
  print(set.contains(Mutable(1))); // Prints: false

  print(set.contains(set.first)); // Prints: false
}

所以现在

Set
处于不一致的状态,它甚至不认为它包含唯一的元素。

© www.soinside.com 2019 - 2024. All rights reserved.