20.所有权III保留所有权


文档摘要

title: 20. 所有权 III 保留所有权 tags: cairo starknet ownership preserve WTF Cairo极简教程: 20. 所有权 III 保留所有权 我最近在学 ,巩固一下细节,也写一个 ,供小白们使用。教程基于 版本。 推特:@0xAAScience|@WTFAcademy WTF Academy 社群:Discord|微信群|官网 wtf.academy 所有代码和教程开源在 github: github.com/WTFAcademy/WTF-Cairo 在 Cairo 中,当数据从一个变量分配到另一个变量或作为函数参数传递时,该数据的所有权会被转移。然而,有时我们希望能够操作数据但又保留其所有权。本章将探讨几种实现此目标的方法。

title: 20. 所有权 III 保留所有权 tags: - cairo - starknet - ownership - preserve

WTF Cairo极简教程: 20. 所有权 III 保留所有权

我最近在学cairo-lang,巩固一下细节,也写一个WTF Cairo极简教程,供小白们使用。教程基于cairo 2.2.0版本。

推特:@0xAA_Science@WTFAcademy_

WTF Academy 社群:Discord微信群官网 wtf.academy

所有代码和教程开源在 github: github.com/WTFAcademy/WTF-Cairo

在 Cairo 中,当数据从一个变量分配到另一个变量或作为函数参数传递时,该数据的所有权会被转移。然而,有时我们希望能够操作数据但又保留其所有权。本章将探讨几种实现此目标的方法。

1. 通过函数返回所有权

你可以设计一个函数,让它将所有权返回给原变量。示例:

use array::ArrayTrait; // 示例函数,移动然后返回所有权 fn return_function(){ let mut x = ArrayTrait::<felt252>::new(); // x 进入作用域 x = return_ownership(x); // 返回 x 的值的所有权 let y = x; // 这行代码有效 } // 返回所有权的函数 fn return_ownership(some_array: Array<felt252>) -> Array<felt252> { some_array }

虽然这种方法允许原变量重新获得所有权,但它需要你自己编写返回值,从而增加了代码的复杂性。

2. Copy 特性

如之前章节所述,如果一个类型实现了 Copy 特性,将其赋值给新变量或传递给函数时,将传递该值的副本,而不会转移所有权。

#[derive(Copy, Drop)] struct Point { x: u128, y: u128, } // 示例,Point 结构体实现了 Copy 特性 fn copy_struct(){ let p1 = Point { x: 5, y: 10 }; let p2 = p1; let p3 = p1; }

但请注意,ArrayDictionary 类型不能实现 Copy 特性。

3. 克隆

Cairo 允许你使用 clone() 方法手动创建一个变量的深复制(deep copy)。

fn clone_example(){ let x = ArrayTrait::<felt252>::new(); // x 进入作用域 let y = x.clone(); // 深度复制 x 并绑定到 y let z = x; // 这有效 }

clone() 的缺点是深度复制一个变量可能会消耗大量的计算资源和 gas。

4. 引用

在 Cairo 中,你可以使用 ref 关键字创建一个值的可变引用(mutable reference)。这个引用在函数结束时会隐式返回,将所有权返回给调用上下文。

fn reference_example(){ let mut x = ArrayTrait::<felt252>::new(); // x 进入作用域 use_reference(ref x); // 将 x 的可变引用传递给函数 let y = x; // 这有效 } fn use_reference(ref some_array: Array<felt252>) { }

请注意,只有可变变量才可以使用 ref 关键字作为引用传递。我们将在下一章更深入地探讨这个话题。

5. 快照

Cairo 中的快照(snapshot)为某个时间点上的值提供了一个不可变的视图。当一个函数接受一个快照作为参数时,它并不接管底层值的所有权。你可以使用快照操作符 @ 创建快照:

fn snapshot_example(){ let x = ArrayTrait::<felt252>::new(); // x 进入作用域 use_snapshot(@x); // 将 x 的快照传递给函数 let y = x; // 这有效 } fn use_snapshot(some_array: @Array<felt252>) { }

我们将在第22章更深入地探讨快照。

总结

在本章中,我们学习了几种在 Cairo 中保留所有权的情况下操纵数据的实用方法。掌握他们会让你写出更好的 Cairo 合约。


作者与出处
原作者: WTFAcademy
来源:WTFAcademy
许可证:MIT
整理: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: WTFAcademy 转发
评论区 (0)
U