一个集合如何确定两个对象在飞镖中是否相等?
How does a set determine that two objects are equal in dart?
我不明白集合如何确定两个对象何时相等。更具体地说,set的add
方法什么时候真正添加了一个新对象,什么时候不作为一个新对象,因为对象已经在set中了?
例如,我有来自以下 class 的对象:
class Action {
final Function function;
final String description;
Action(this.function, this.description);
call() => function();
toString() => description;
}
现在我认为以下集合将包含 2 个元素,因为其中 2 个元素相等:
void main() {
Set<Action> actions = new Set()
..add(new Action(() => print("a"), "print a"))
..add(new Action(() => print("a"), "print a"))
..add(new Action(() => print("b"), "print b"));
}
但是,这个集合包含 3 个 Action
对象。参见demo。我怎样才能确保相等的对象在集合中被视为相等?
有关 Dart 中 operator==
的综合文章,请参阅 http://work.j832.com/2014/05/equality-and-dart.html
它只是检查它们是否相等 a == b
您可以覆盖 ==
运算符来自定义此行为。请记住,当 ==
运算符被覆盖时, hashCode
也应该被覆盖。
class Action {
@override
bool operator==(other) {
// Dart ensures that operator== isn't called with null
// if(other == null) {
// return false;
// }
if(other is! Action) {
return false;
}
return description == (other as Action).description;
}
// hashCode must never change otherwise the value can't
// be found anymore for example when used as key
// in hashMaps therefore we cache it after first creation.
// If you want to combine more values in hashCode creation
// see
// This is just one attempt, depending on your requirements
// different handling might be more appropriate.
// As far as I am aware there is no correct answer for
// objects where the members taking part of hashCode and
// equality calculation are mutable.
// See also
int _hashCode;
@override
int get hashCode {
if(_hashCode == null) {
_hashCode = description.hashCode
}
return _hashCode;
}
// when the key (description) is immutable and the only
// member of the key you can just use
// int get hashCode => description.hashCode
}
尝试 DartPad
下面是一个测试顶级函数、静态方法和实例方法是否相等的示例:
void foo() {} // A top-level function
class A {
static void bar() {} // A static method
void baz() {} // An instance method
}
void main() {
var x;
// Comparing top-level functions.
x = foo;
assert(foo == x);
// Comparing static methods.
x = A.bar;
assert(A.bar == x);
// Comparing instance methods.
var v = A(); // Instance #1 of A
var w = A(); // Instance #2 of A
var y = w;
x = w.baz;
// These closures refer to the same instance (#2),
// so they're equal.
assert(y.baz == x);
// These closures refer to different instances,
// so they're unequal.
assert(v.baz != w.baz);
}
我不明白集合如何确定两个对象何时相等。更具体地说,set的add
方法什么时候真正添加了一个新对象,什么时候不作为一个新对象,因为对象已经在set中了?
例如,我有来自以下 class 的对象:
class Action {
final Function function;
final String description;
Action(this.function, this.description);
call() => function();
toString() => description;
}
现在我认为以下集合将包含 2 个元素,因为其中 2 个元素相等:
void main() {
Set<Action> actions = new Set()
..add(new Action(() => print("a"), "print a"))
..add(new Action(() => print("a"), "print a"))
..add(new Action(() => print("b"), "print b"));
}
但是,这个集合包含 3 个 Action
对象。参见demo。我怎样才能确保相等的对象在集合中被视为相等?
有关 Dart 中 operator==
的综合文章,请参阅 http://work.j832.com/2014/05/equality-and-dart.html
它只是检查它们是否相等 a == b
您可以覆盖 ==
运算符来自定义此行为。请记住,当 ==
运算符被覆盖时, hashCode
也应该被覆盖。
class Action {
@override
bool operator==(other) {
// Dart ensures that operator== isn't called with null
// if(other == null) {
// return false;
// }
if(other is! Action) {
return false;
}
return description == (other as Action).description;
}
// hashCode must never change otherwise the value can't
// be found anymore for example when used as key
// in hashMaps therefore we cache it after first creation.
// If you want to combine more values in hashCode creation
// see
// This is just one attempt, depending on your requirements
// different handling might be more appropriate.
// As far as I am aware there is no correct answer for
// objects where the members taking part of hashCode and
// equality calculation are mutable.
// See also
int _hashCode;
@override
int get hashCode {
if(_hashCode == null) {
_hashCode = description.hashCode
}
return _hashCode;
}
// when the key (description) is immutable and the only
// member of the key you can just use
// int get hashCode => description.hashCode
}
尝试 DartPad
下面是一个测试顶级函数、静态方法和实例方法是否相等的示例:
void foo() {} // A top-level function
class A {
static void bar() {} // A static method
void baz() {} // An instance method
}
void main() {
var x;
// Comparing top-level functions.
x = foo;
assert(foo == x);
// Comparing static methods.
x = A.bar;
assert(A.bar == x);
// Comparing instance methods.
var v = A(); // Instance #1 of A
var w = A(); // Instance #2 of A
var y = w;
x = w.baz;
// These closures refer to the same instance (#2),
// so they're equal.
assert(y.baz == x);
// These closures refer to different instances,
// so they're unequal.
assert(v.baz != w.baz);
}