本文详细讲解了如何将Solidity中的函数可见性和合约继承概念化到Solana中,并提供了Rust语言中实现这些概念的代码示例。
今天我们将学习如何在 Solana 中构思 Solidity 的函数可见性和合约继承。Solidity 中有四种函数可见性级别,它们是:
让我们在 Solana 中实现相同的功能,好吗?
自第一天起到现在我们定义的所有函数都是公共函数:
pub fn my_public_function(ctx: Context<Initialize>) -> Result<()> {
// 函数逻辑...
Ok(())
}
在函数声明前添加 pub
关键字,从而使函数变为公共。
你不能移除标记为 #[program]
的模块 (mod) 内部的函数的 pub
关键字。这将导致无法编译。
在 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<()> {
// 从其父模块内部调用...
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!