Rust 和 Solana 中的可见性与“继承”

  • RareSkills
  • 发布于 2024-02-19 15:59
  • 阅读 196

本文详细讲解了如何将Solidity中的函数可见性和合约继承概念化到Solana中,并提供了Rust语言中实现这些概念的代码示例。

Rust function visibillity

今天我们将学习如何在 Solana 中构思 Solidity 的函数可见性和合约继承。Solidity 中有四种函数可见性级别,它们是:

  • public – 从合约内部和外部均可访问。
  • external – 从合约外部仅可访问。
  • internal – 从合约内部和继承合约中可访问。
  • private – 仅在合约内部可访问。

让我们在 Solana 中实现相同的功能,好吗?

公共函数

自第一天起到现在我们定义的所有函数都是公共函数:

pub fn my_public_function(ctx: Context<Initialize>) -> Result<()> {
    // 函数逻辑...

    Ok(())
}

在函数声明前添加 pub 关键字,从而使函数变为公共。

你不能移除标记为 #[program] 的模块 (mod) 内部的函数的 pub 关键字。这将导致无法编译。

不用太担心 external 和 public 之间的区别

在 Solana 程序中,调用自己公共函数通常是不方便的。如果 Solana 程序中存在 pub 函数,从实际角度来看,你可以将其视作为在 Solidity 中的外部函数。

如果你想在同一个 Solana 程序中调用公共函数,包裹这个公共函数并调用该内部实现函数要更容易。

私有和内部函数

虽然你不能在使用 #[program] 宏的模块中声明没有 pub 的函数,但你可以在文件内部声明函数。考虑以下代码:

use anchor_lang::prelude::*;

declare_id!("F26bvRaY1ut3TD1NhrXMsKHpssxF2PAUQ7SjZtnrLkaM");

#[program]
pub mod func_test {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        // -------- 调用一个“私有”函数 --------
        let u = get_a_num();
        msg!("{}", u);
        Ok(())
    }
}

// ------- 我们在此声明了一个非 pub 函数 -------
fn get_a_num() -> u64 {
    2
}

#[derive(Accounts)]
pub struct Initialize {}

这将按预期运行并记录。

如果你想构建简单的 Solana 程序,这些是你真正需要了解的有关公共和内部函数的所有内容。但如果你希望比仅仅在文件中声明一堆函数更好地组织代码,你可以继续深入。Rust,因此 Solana,没有像 Solidity 那样的“类”,因为 Rust 不是面向对象的。因此,“私有”和“内部”之间的区别在 Rust 中没有直接类比。

Rust 使用模块来组织代码。模块内外函数的可见性在Rust 文档的可见性和隐私部分中有很好的讨论,但我们将添加自己针对 Solana 的见解。

内部函数

通过在程序模块内定义函数并确保其在其自己的模块及导入或使用它的其他模块内可访问来实现。这是怎么做的:

use anchor_lang::prelude::*;

declare_id!("53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX");

#[program]
pub mod func_visibility {
    use super::*;

    pub fn initialize(_ctx: Context<Initialize>) -> Result<()> {
        // 从其父模块内部调用 internal_function
        some_internal_function::internal_function();

        Ok(())
    }

    pub mod some_internal_function {
        pub fn internal_function() {
            // 内部函数逻辑...
        }
    }
}

mod do_something {
    // 导入 func_visibility 模块
    use crate::func_visibility;

    pub fn some_func_here() {
        // 从外部其父模块调用 internal_function
        func_visibility::some_internal_function::internal_function();

        // 做其他事情...
    }
}

#[derive(Accounts)]
pub struct Initialize {}

构建程序后,如果导航到 ./target/idl/func_visibility.json 文件,你将看到定义在 some_internal_function 模块中的函数没有被包含在构建程序中。这表明 some_internal_function 函数是内部的,仅能在程序内部及任何导入或使用它的程序中访问。

从上面的例子中,我们能够从其“父”模块(func_visibility)内部访问 internal_function 函数,也能从 func_visibility 模块外的单独模块中访问(do_something)。

私有函数

在特定模块内定义函数并确保它们不会暴露在该作用域之外就是实现私有可见性的一种方式:


use anchor_lang::prelude::*;

declare_id!("53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX");

#[program]
pub mod func_visibility {
    use super::*;

    pub fn initialize(_ctx: Context<Initialize>) -> Result<()> {
        // 从其父模块内部调用...

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

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。
该文章收录于 Solana 60 天课程
43 订阅 33 篇文章

0 条评论

请先 登录 后评论
RareSkills
RareSkills
https://www.rareskills.io/