我使用Piece class
作为Map的密钥。
但是运行此代码后,发生了错误Uncaught exception:
C.JSNull_methods.$indexSet is not a function
。
class Piece {
int type;
Piece(this.type);
}
void main() {
Map<Piece, int> hand;
hand[Piece(5)] = 5;
if (hand.containsKey(Piece(5))) {
print("contains");
}
print('${hand[Piece(5)]}');
}
在dart-lang中,如何使用class
作为Map的键?
答案 0 :(得分:0)
首先,您遇到的错误与将类型用作键无关,但是在您从未初始化hand变量之前就已发生。因此,您需要这样做:
Map<Piece, int> hand = {};
现在,您将不会收到异常,但是您的代码将无法正常工作,因为hand.containsKey(Piece(5))
将返回false,而print('${hand[Piece(5)]}')
将返回null
。
这是因为映射Map<Piece, int>
没有使用Type作为键,而是使用了Piece
类型的对象。因此,如果我们将您的代码放在这里:
Map<Piece, int> hand = {};
hand[Piece(5)] = 5;
if (hand.containsKey(Piece(5))) {
print("contains");
}
print('${hand[Piece(5)]}');
您在这里创建一个新的Piece类型的对象实例,每种类型您正在编写“ Piece(5)”。由于每个对象都是片断的单独实例,因此您将不会收到保存的值5,因为为与请求不同的对象保存了值5。
有多种解决方案,我不知道哪一种最适合您。但是在这种情况下,简单的解决方案是只创建一个Piece实例并重用该实例:
void main() {
Map<Piece, int> hand = {};
final piece = Piece(5);
hand[piece] = 5;
if (hand.containsKey(piece)) {
print("contains");
}
print('${hand[piece]}');
}
或者为Piece类创建一个const构造函数,以便将具有相同参数的实例放入同一对象。此解决方案要求int type
是最终的,因为您不能编辑const构造的对象(因为它是常量):
class Piece {
final int type;
const Piece(this.type);
}
void main() {
Map<Piece, int> hand = {};
hand[const Piece(5)] = 5;
if (hand.containsKey(const Piece(5))) {
print("contains");
}
print('${hand[const Piece(5)]}');
}
请注意,每当您需要确保实例将为相同的参数返回相同的对象时,都需要在对象实例化前加上const
,例如“ const Piece(5)”。