在计算器函数中使用整数
在本教程中,您将编写一个简单的计算器程序,该程序创建一个具有多个公共入口点函数的单个参与者,以执行基本的算术运算。
在本教程中,actor 被命名为 Calc
。
该程序使用 cell
变量来包含一个整数,该整数表示计算器操作的当前结果。
该程序支持以下函数调用:
-
add
函数调用接受输入并执行加法。 -
sub
函数调用接受输入并执行减法。 -
mul
函数调用接受输入并执行乘法。 -
div
函数调用接受输入并执行除法。 -
clearall
函数清除作为先前操作结果存储的`cell` 值,将`cell` 值重置为零。
div
函数还包括防止程序试图除以零的代码。
创建一个新项目
要为本教程创建一个新项目:
-
如果您还没有打开一个终端外壳,请在您的本地计算机上打开一个终端外壳。
-
更改为您用于 Internet Computer 项目的文件夹(如果您正在使用一个)。
-
通过运行以下命令创建一个新项目:
dfx new calc
-
通过运行以下命令切换到您的项目目录:
cd calc
修改默认配置
对于本教程,让我们修改默认的“dfx.json”配置文件,为其主程序使用更具体的名称。
修改默认的 dfx.json
配置文件:
-
在文本编辑器中打开
+dxf.json
配置文件。 -
将
main
键设置从默认的main.mo
程序名称更改为calc_main.mo
。例如:
"main": "src/calc/calc_main.mo",
对于本教程,将源文件的名称从
main.mo
更改为calc_main.mo
只是说明了dfx.json
配置文件中的设置如何确定要编译的源文件。在更复杂的 dapp 中,您可能有多个源文件而不是单个
main
程序文件。 更复杂的应用程序可能还具有多个源文件之间的特定依赖关系,您需要使用dfx.json
配置文件中的设置来管理这些依赖关系。 在这样的场景中——在你的“dfx.json”文件中定义了多个容器和程序——拥有多个名为“main.mo”的文件可能会使你的工作区导航变得更加困难。 您为每个程序选择的名称并不重要,但重要的是您在dfx.json
文件中设置的名称与文件系统中的程序名称相匹配。 -
保存更改并关闭文件以继续。
修改默认程序
对于本教程,您需要将默认程序替换为执行基本算术运算的程序。
要替换默认程序:
-
如果需要,请检查您是否仍在项目目录中。
-
复制模板
main.mo
文件,通过运行以下命令创建一个名为calc_main.mo
的新文件:cp src/calc/main.mo src/calc/calc_main.mo
-
在文本编辑器中打开
src/calc/calc_main.mo
文件并删除现有内容。 -
将以下示例代码复制并粘贴到
calc_main.mo
文件中:// This single-cell calculator defines one calculator instruction per // public entry point (add, sub, mul, div). // Create a simple Calc actor. actor Calc { var cell : Int = 0; // Define functions to add, subtract, multiply, and divide public func add(n:Int) : async Int { cell += n; cell }; public func sub(n:Int) : async Int { cell -= n; cell }; public func mul(n:Int) : async Int { cell *= n; cell }; public func div(n:Int) : async ?Int { if ( n == 0 ) { return null // null indicates div-by-zero error } else { cell /= n; ?cell } }; // Clear the calculator and reset to zero public func clearall() : async Int { if (cell : Int != 0) cell -= cell; return cell }; };
您可能会注意到此示例代码使用整数 (
Int
) 数据类型,使您能够使用正数或负数。 如果您想将此计算器代码中的函数限制为仅使用正数,您可以将数据类型更改为仅允许自然 (Nat
) 数据。 -
保存更改并关闭文件以继续。
启动本地容器执行环境
在构建 calc
项目之前,您需要连接到在您的开发环境中本地运行的容器执行环境,或者您需要连接到您可以访问的子网。
在本地启动网络需要一个 dfx.json
文件,因此您应该确保您位于项目的根目录中。
对于本教程,您应该有两个独立的终端 shell,以便您可以在一个终端中启动和查看网络操作并在另一个终端中管理您的项目。
启动本地容器执行环境:
-
在本地计算机上打开一个新的终端窗口或选项卡。
-
如有必要,导航到项目的根目录。
-
您现在应该打开了两个终端。
-
您应该将 project 目录 作为您的 current 工作目录。
-
-
通过运行以下命令在您的机器上启动本地容器执行环境:
dfx start
启动本地网络后,终端会显示有关网络操作的消息。
-
让显示网络操作的终端保持打开状态,然后将注意力转移到创建新项目的原始终端。
注册、构建和部署 dapp
连接到本地容器执行环境后,您可以在本地注册、构建和部署 dapp。
要在本地部署 dapp:
-
如果需要,请检查您是否仍在项目的根目录中。
-
通过运行以下命令注册、构建和部署您的 dapp:
dfx deploy
dfx deploy
命令输出显示有关它执行的操作的信息。
验证容器上的计算器功能
您现在在本地容器执行环境中部署了一个程序作为*容器智能合约*。
您可以使用 dfx canister call
命令测试程序。
要测试您已部署的程序:
-
使用
dfx canister call
命令调用calc
容器add
函数,并通过运行以下命令将输入参数10
传递给它:dfx canister call calc add '(10)'
当您传递由单引号和括号括起来的参数时,接口描述语言 (IDL) 会解析参数类型,因此您无需手动指定参数类型。
验证该命令是否返回
add
函数的预期值。 例如,程序显示类似于以下的输出:(10)
-
调用
mul
函数并通过运行以下命令将输入参数3
传递给它:dfx canister call calc mul '(3)'
验证命令是否返回
mul
函数的预期值。 例如,程序显示类似于以下的输出:(30)
-
调用`sub
函数并通过运行以下命令将
number类型的输入参数
5`传递给它:dfx canister call calc sub '(5)'
验证命令是否返回
sub
函数的预期值。 例如,程序显示类似于以下的输出:(25)
-
调用
div
函数并通过运行以下命令将输入参数5
传递给它:dfx canister call calc div '(5)'
验证命令是否返回
div
函数的预期值。 例如,程序显示类似于以下的输出:(opt 5)
您可能会注意到
div
函数返回一个可选结果。 该程序使结果可选,以使div
函数在除零错误的情况下返回null
。因为这个程序中的单元格变量是一个整数,你也可以调用它的函数并指定负输入值。 例如,您可以运行以下命令:
dfx canister call calc mul '(-4)'
which returns:
(-20)
-
调用
+clearall
函数并验证它是否将+cell
值重置为零:dfx canister call calc clearall
例如,程序显示类似于以下的输出:
(0)
在浏览器中测试功能
容器接口描述语言(通常称为 Candid 或更一般地称为 IDL)为指定容器智能合约的签名提供了一种通用语言。 Candid 为您提供了一种统一的方式来与用不同语言编写或使用不同工具访问的容器智能合约进行交互。 例如,无论底层程序是原生 Rust、JavaScript 还是 Motoko,Candid 都能提供一致的服务视图。 Candid 还启用了不同的工具——例如`dfx` 命令行界面和网络神经系统 dapp——来共享服务的通用描述。
基于 actor 的类型签名,Candid 还提供了一个 Web 界面,允许您调用容器函数进行测试和调试。
使用 dfx deploy
或 dfx canister install
命令在本地容器执行环境中部署项目后,您可以在浏览器中访问 Candid Web 界面端点。
此 Web 界面 — Candid UI — 以表单形式公开服务描述,使您无需编写任何前端代码即可快速查看和测试功能并尝试输入不同的数据类型。
要使用 Candid Web 界面测试容器功能:
dfx canister id __Candid_UI
命令查找与当前项目关联的 Candid UI 容器标识符。+
dfx canister id __Candid_UI
+ 该命令显示 Candid UI 的容器标识符,输出类似于以下内容:
+
r7inp-6aaaa-aaaaa-aaabq-cai
+ . 复制 Candid UI 容器标识符,使其在剪贴板中可用。 . 如果您已停止本地容器执行环境,请通过运行以下命令在本地重新启动它:
+
dfx start --background
-
打开浏览器并导航到
dfx.json
配置文件中指定的地址和端口号。默认情况下,本地容器执行环境绑定到`127.0.0.1:8000`地址和端口号。
-
将所需的
canisterId
参数和dfx canister id __Candid_UI
命令返回的 Candid UI 容器标识符添加到 URL。例如,完整的 URL 应该类似于以下内容,但带有由
dfx canister id __Candid_UI
命令返回的`CANDID-UI-CANISTER-IDENTIFIER`:http://127.0.0.1:8000/?canisterId=<CANDID-UI-CANISTER-IDENTIFIER>
例如,对于 Candid UI 的示例容器标识符,如上所示,可能如下所示:
http://127.0.0.1:8000/?canisterId=r7inp-6aaaa-aaaaa-aaabq-cai
然后,浏览器会显示一个表单供您指定容器标识符或选择 Candid 描述 (
.did
) 文件。 请注意,此字段是指您要与之交互的容器的容器标识符(与我们在上一步中使用的 Candid UI 的容器标识符相反)。 -
在 Provide a canister ID 字段中指定要测试的容器的容器标识符,然后单击 Go 以显示服务描述。
如果您不确定要使用哪个容器标识符,可以运行
dfx canister id
命令来查找特定容器名称的标识符。 例如,要获取名为my_counter
的容器的容器标识符,您可以使用:dfx canister id my_counter
-
查看 dapp 中定义的函数调用和类型列表。
-
为函数键入适当类型的值或单击 Random 生成值,然后单击 Call 或 Query 以查看结果。
请注意,根据数据类型,Candid 界面可能会显示用于测试功能的其他配置设置。 例如,如果一个函数接受一个数组,您可能需要在输入值之前指定数组中的项目数。