减少冗余模板代码

在上一节中,我们看到了这样一个示例:在一个没有任何相应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 }));

        }
    }
}

Last change: 2023-09-20, commit: cbb0049