减少冗余模板代码
在上一节中,我们看到了这样一个示例:在一个没有任何相应trait的合约中,有一个实现块。
#[generate_trait]
impl InternalFunctions of InternalFunctionsTrait {
fn _store_name(
ref self: ContractState,
user: ContractAddress,
name: felt252,
registration_type: RegistrationType
) {
let mut total_names = self.total_names.read();
self.names.write(user, name);
self.registration_type.write(user, registration_type);
self.total_names.write(total_names + 1);
self.emit(StoredName { user: user, name: name });
}
}
这并不是我们第一次遇到这个属性,我们已经在在Cairo中使用 Traits
(./ch08-02-traits-in-cairo.md) 中讨论过它。在本节中,我们将更深入地研究它,并看看它在合约中的使用方式。
回想一下,为了在函数中访问 ContractState,该函数必须定义在泛型参数为 ContractState
的实现块中。这意味着我们首先需要定义一个接受TContractState
的泛型trait,然后为ContractState
类型实现这个trait。
但是通过使用 #[generate_trait]
属性,我们可以跳过整个过程,从而简单地直接定义实现块,不需要任何泛型参数,并在我们的函数中使用 self.ContractState
属性。
如果我们必须手动定义 InternalFunctions
所实现的trait,它将看起来像这样:
trait InternalFunctionsTrait<TContractState> {
fn _store_name(ref self: TContractState, user: ContractAddress, name: felt252);
}
impl InternalFunctions of InternalFunctionsTrait<ContractState> {
fn _store_name(ref self: ContractState, user: ContractAddress, name: felt252) {
let mut total_names = self.total_names.read();
self.names.write(user, name);
self.total_names.write(total_names + 1);
self.emit(Event::StoredName(StoredName { user: user, name: name }));
}
}
}