Solana 学习开发之旅

2025年04月03日更新 36 人订阅
原价: ¥ 28 限时优惠
专栏简介 【Solana】使用 CLI 创建 SPL 标准的 Token 以及基础使用 【Solana】完善 SPL Token 名称和 Logo 【Solana】创建 SPL 标准的 NFT 以及完善 metadata 【Solana】一些基本的js脚本 【Solana】Anchor 框架使用笔记 【Solana】Anchor 示例:通过 CPI 实现 Sol 转账与手续费收取 Solana Hello World: 安装与开发指南 Solana 与 Rust 算术入门—从 Solidity 到 Anchor Solana Anchor 程序接口定义语言(IDL) Solana Anchor 框架下的 Require 与自定义错误 Solana 程序:支持升级与无构造函数实现 Solidity 开发者必知的 Rust 语法基础 Rust 的独特语法解析 Rust 类函数宏解析 Rust 结构体、属性宏与自定义派生宏 Rust 与 Solana 中的可见性及模块化复用 Solana 中的时钟与其他区块变量 Solana 系统变量详解 Solana 日志、事件日志与历史交易查询 Solana 中的Tx.origin、msg.sender 和 onlyOwner Solana 计算单元与交易费用概述 Solana 与 Anchor 中的账户初始化 Solana 计数器教程:账户数据的读写 使用 Solana Web3.js 和 Anchor 读取账户数据 在 Solana 中实现映射表与嵌套映射表 Solana 存储成本、最大容量与账户调整 在 Anchor 中读取账户余额:Solana 的 address(account).balance Solana 中的函数修饰符与 Fallback 函数:为何不存在 Solana 中的 SOL 转移与分割:取代 msg.value 的设计 使用不同签名者修改账户:Solana 中的权限控制 PDA 与密钥对账户:Solana 中的地址与权限模型 Anchor 中的 init_if_needed 与重新初始化攻击防范 Solana 中的 Multicall:批处理交易和交易大小的限制 Solana 中的 Owner 和 Authority 删除和关闭 Solana 中的账户和程序 在 Anchor 中的 #[derive(Accounts)] 不同类型的账户 在链上读取另一个 Anchor 程序的账户数据 Anchor 中的跨程序调用

Rust 结构体、属性宏与自定义派生宏

  • 0xE
  • 发布于 2025-03-24 13:19
  • 阅读 1272

在 Rust 中,属性宏和自定义派生宏用于在编译时处理代码,通常为结构体添加功能或修改其定义。本文将解析这些宏的工作原理,并介绍与结构体相关的 impl 和 trait。

在 Rust 中,属性宏和自定义派生宏用于在编译时处理代码,通常为结构体添加功能或修改其定义。本文将解析这些宏的工作原理,并介绍与结构体相关的 impl 和 trait。


结构体的实现:impl

以下是一个简单的 Person 结构体:

struct Person {
    name: String,
    age: u8,
}

在 Rust 中,通过 impl 为结构体定义关联函数和方法。例如:

struct Person {
    age: u8,
    name: String,
}

impl Person {
    // 创建新的 Person 实例
    fn new(name: String, age: u8) -> Self {
        Person { name, age }
    }

    // 判断是否达到饮酒年龄
    fn can_drink(&self) -> bool {
        self.age >= 21
    }

    // 返回一年后的年龄
    fn age_in_one_year(&self) -> u8 {
        self.age + 1
    }
}

fn main() {
    let person = Person::new(String::from("Jesserc"), 19);
    println!("{:?}", person.can_drink()); // false
    println!("{:?}", person.age_in_one_year()); // 20
    println!("{:?}", person.name); // "Jesserc"
}

说明

  • new 是关联函数,通过 Person::new 调用。
  • can_drink 和 age_in_one_year 是方法,通过实例调用。

Rust 的 Trait

Trait 定义了类型间的共享行为,类似 Solidity 的接口。例如,为 Car 和 Boat 定义速度转换:

trait Speed {
    fn get_speed_kph(&self) -> f64;
}

struct Car {
    speed_mph: f64,
}

struct Boat {
    speed_knots: f64,
}

impl Speed for Car {
    fn get_speed_kph(&self) -> f64 {
        self.speed_mph * 1.60934 // 英里/小时转公里/小时
    }
}

impl Speed for Boat {
    fn get_speed_kph(&self) -> f64 {
        self.speed_knots * 1.852 // 节转公里/小时
    }
}

fn main() {
    let car = Car { speed_mph: 60.0 };
    let boat = Boat { speed_knots: 30.0 };
    println!("Car Speed: {} km/h", car.get_speed_kph()); // 96.5604 km/h
    println!("Boat Speed: {} km/h", boat.get_speed_kph()); // 55.56 km/h
}

说明:Speed Trait 确保 Car 和 Boat 都实现 get_speed_kph。


宏如何操作结构体

在 Solana 的 Anchor 框架中,常用类函数宏(如 println!)、属性宏(如 #[program])和自定义派生宏(如 #[derive(Accounts)])。以下通过示例展示属性宏的强大能力。

示例 1:属性宏添加字段

我们创建一个属性宏,为结构体添加字段并生成方法。

项目设置

cargo new macro-demo --lib
cd macro-demo
touch src/main.rs

Cargo.toml:

[lib]
proc-macro = true

[dependencies]
syn = {version="1.0.57", features=["full","fold"]}
quote = "1.0.8"

主程序(src/main.rs)


use macro_demo::*;

#[foo_bar_attribute]
struct MyStruct {
    baz: i32,
}

fn main() {
    let demo = MyStruct::default();
    println!("struct is {:?}", demo);...

剩余50%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论