Solidity开发者的Rust基础

  • RareSkills
  • 发布于 2024-02-15 11:28
  • 阅读 265

本教程深入探讨了Solidity和Rust在控制流、数组、映射、结构体和常量等方面的语法对比,旨在帮助掌握Solidity的开发者快速上手Rust编程。

Hero image showing Rust : the easy parts

本教程介绍了在 Solidity 中最常用的语法,并展示了其在 Rust 中的等价实现。

如果你想了解 Rust 与 Solidity 之间的高层次差异,请查看链接的教程。本教程假设你已经了解 Solidity,假如你对 Solidity 不熟悉,请查看我们免费的 Solidity 教程

创建一个名为 tryrust 的新 Solana Anchor 项目并设置环境。

条件语句

我们可以说,开发人员在 Solidity 中可以根据特定条件控制执行流程的方式有 2 种:

  • If-Else 语句
  • 三元运算符

现在让我们看看上述内容在 Solidity 中的实现,以及它们在 Solana 中的翻译。

If-Else 语句

在 Solidity 中:

function ageChecker(uint256 age) public pure returns (string memory) {
    if (age >= 18) {
        return "你已满 18 岁或以上";
    } else {
        return "你未满 18 岁";
    }
}

在 Solana 中,在 lib.rs 中添加一个名为 age_checker 的新函数:

pub fn age_checker(ctx: Context<Initialize>, age: u64) -> Result<()> {
    if age >= 18 {
        msg!("你已满 18 岁或以上");
    } else {
        msg!("你未满 18 岁");
    }
    Ok(())
 }

请注意,条件 age >= 18 没有括号——这在 if 语句中是可选的。

要测试,请在 ./tests/tryrust.ts 中添加另一个 it 块:

it("年龄检查", async () => {
    // 在这里添加你的测试。
    const tx = await program.methods.ageChecker(new anchor.BN(35)).rpc();
    console.log("你的交易签名", tx);
});

运行测试后,我们应该得到以下日志:

Transaction executed in slot 77791:
  Signature: 2Av18ej2YjkRhzybbccPpwEtkw73VcBpDPZgC9iKrmf6mvwbqjA517garhrntWxKAM1ULL2eAv5vDWJ3SjnFZq6j
  Status: Ok
  Log Messages:
    Program 53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX invoke [1]
    Program log: Instruction: AgeChecker
    Program log: 你已满 18 岁或以上
    Program 53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX consumed 440 of 200000 compute units
    Program 53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX success

三元运算符

在 Solidity 中将 if-else 语句分配给变量:

function ageChecker(uint256 age) public pure returns (bool a) {
    a = age % 2 == 0 ? true : false;
}

在 Solana 中,我们基本上只是将一个 if-else 语句分配给一个变量。下面的 Solana 程序与上述相同:

pub fn age_checker(ctx: Context<Initialize>, age: u64) -> Result<()> {
    let result = if age >= 18 {"你已满 18 岁或以上"} else { "你未满 18 岁" };
    msg!("{:?}", result);
    Ok(())
}

请注意,在 Rust 的三元运算符示例中,if/else 块以分号结尾,因为这是分配给一个变量的。

还要注意,内部值没有以分号结尾,因为它作为返回值返回给变量,就像在表达式而不是语句的情况下不在 Ok(()) 之后加分号一样。

如果年龄是偶数,程序将输出 true,否则为 false:

Transaction executed in slot 102358:
  Signature: 2zohZKhY56rLb7myFs8kabdwULJALENyvyFS5LC6yLM264BnkwsThMnotHNAssJbQEzQpmK4yd3ozs3zhG3GH1Gx
  Status: Ok
  Log Messages:
    Program 53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX invoke [1]
    Program log: Instruction: AgeChecker
    Program log: true
    Program 53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX consumed 792 of 200000 compute units
    Program 53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX success

Rust 还有一个更强大的控制流结构叫做 match。让我们看看下面的使用 match 的示例:

pub fn age_checker(ctx: Context<Initialize>, age: u64) -> Result<()> {
    match age {
        1 => {
            // 如果年龄等于 1 则执行的代码块
            msg!("年龄是 1");
        },
        2 | 3 => {
            // 如果年龄等于 2 或 3 则执行的代码块
            msg!("年龄是 2 或 3");
        },
        4..=6 => {
            // 如果年龄在 4 到 6(包括)之间则执行的代码块
            msg!("年龄在 4 到 6 之间");
        },
        _ => {
            // 任何其他年龄的代码块
            msg!("年龄是其他值");
        }
    }
    Ok(())
}

For 循环

我们知道,for 循环允许遍历范围、集合和其他可迭代对象,在 Solidity 中是这样写的:

function loopOverSmth() public {
    for (uint256 i=0; i < 10; i++) {
        // 做一些事情...
    }
}

这在 Solana(Rust)中的等价实现为:

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
    for i in 0..10 {
        // 做一些事情...
    }

    Ok(())
}

是的,简单如斯,但我们如何使用自定义步长遍历范围呢?以下是在 Solidity 中的预期行为:

function loopOverSmth() public {
    for (uint256 i=0; i < 10; i+=2) {
        // 做一些事情...

        // 将 i 增加 2
    }
}

在 Solana 中使用 step_by 的等价实现是:

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
    for i in (0..10).step_by(2) {
        // 做一些事情...

        msg!("{}", i);
    }     

    Ok(())
}

运行测试后,我们应该获得以下日志:

Transaction executed in slot 126442:
  Signature: 3BSPA11TZVSbF8krjMnge1fgwNsL9odknD2twAsDeYEF39AzaJy1c5TmFCt6LEzLtvWnjzx7VyFKJ4VT1KQBpiwm
  Status: Ok
  Log Messages:
    Program 53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX invoke [1]
    Program log: Instruction: Initialize
    Program log: 0
    Program log: 2
    Program log: 4
    Program log: 6
    Program log: 8
    Program 53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX consumed 2830 of 200000 compute units
    Program 53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX success

数组和向量

Rust 和 Solidity 在数组支持上有所不同。虽然 Solidity 原生支持固定和动态数组,但 Rust 仅内置支持固定数组。如果你想要动态长度的列表,请使用向量。

现在,让我们看一些示例,演示...

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

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

0 条评论

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