是否存在不遵循不可变导致错误的哈希结果的真实案例?
我做了一个测试用例来测试非不可变类,并期望它会出现错误。实际上,我们对此没有任何问题,并且 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);
});
}
是否存在不遵循不可变导致错误的哈希结果的真实案例?
一个简单的例子:
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
处于不一致的状态,它甚至不认为它包含唯一的元素。