1.11「Motoko——Sharing data and behavior」

1.11「Motoko——Sharing data and behavior」

回想一下,在 Motoko 中,可变(mutable)的状态对于actor来说总是私有(private)的。

但是,两个actor可以共享消息数据,这些消息可以引用(refer to)actor,包括他们自己和彼此。此外,如果这些函数是共享(shared)的,消息可以引用(refer to)单个函数。

通过这些机制,两个actor可以通过异步(asynchronous)消息传递来协调它们的行为。

带有actor的Publisher-subscriber模式:

本节中的示例通过关注publish-subscribe模式的变体,演示actor如何共享其功能。在Publisher-subscriber模式中,一个publishing actor记录subscriber actor列表,以便在publisher的状态中发生值得注意的事情时进行通知。例如,如果publisher actor发布了一篇新文章,则会通知subscriber actor有一篇新文章可用。

下面的示例使用 Motoko 中的两个actor来构建Publisher-subscriber关系的变体。

PS:要查看使用此模式的工作项目的完整代码,请参阅示例存储库中的 pubsub 示例。

Subscriber actor:

下面的 Subscriber actor类型提供了一个可能的接口,以便subscriber actor和publisher actor分别公开和调用:

type Subscriber = actor {
  notify : () -> ()
};
  • Publisher使用此类型定义数据结构以将其Subscribers存储为数据。
  • 每个Subscriber actor公开一个 notify update 函数,如上面的Subscriber actor类型签名中所述。

注意,子类型(sub-typing)允许Subscriber actor包含此类型定义中未列出的其他方法。

为简单起见,假设 notify 函数接受相关的通知数据,并向Publisher返回一些关于Subscriber的新状态消息。例如,Subscriber可能根据通知数据返回对其订阅设置的更改。

Publisher actor:

Publisher端的代码存储Subscribers数组。为简单起见,假设每个Subscriber只使用一个subscribe函数订阅自己一次。

import Array "mo:base/Array";

actor Publisher {
    var subs: [Subscriber] = [];

    public func subscribe(sub: Subscriber) {
        subs := Array.append<Subscriber>(subs, [sub]);
    };

    public func publish() {
        for (sub in subs.vals()) {
          sub.notify();
        };
    };
};

稍后,当某个未指定的外部代理调用publish函数时,所有Subscribers都会收到通知消息,如上面给出的Subscriber类型中所定义的。

Subscriber methods:

在最简单的情况下,Subscriber actor具有以下方法:

  • 使用 init 方法订阅来自Publisher的通知。
  • 按照上面给出的Subscriber类型中的 notify 函数指定的方式,作为其中一个subscribed actor接收通知。
  • 允许对累积状态的查询,在这个示例代码中,它只是一个get方法,用于获取接收到的通知和存储在 count 变量中的通知数。

下面的代码说明了如何实现这些方法:

actor Subscriber {
  var count: Nat = 0;
  public func init() {
    Publisher.subscribe(Subscriber);
  };
  public func notify() {
    count += 1;
  };
  public func get() : async Nat {
    count
  };
}

actor假设只调用其 init 函数一次,但并不强制执行这个函数。在 init 函数中,Subscriber actor传递一个类型为 actor { notify: ()→()} ; (上面在本地,名为Subscriber)的自身的引用。

如果多次调用,actor将多次订阅自己,并从Publisher那里接收多个(重复的)通知。这种脆弱性是我们上面展示的基本Publisher-subscriber模式的结果。如果更加小心,更高级的Publisher actor可以检查重复的Subscriber actor,并忽略他们。

Sharing functions among actors:

在 Motoko 中,共享的actor函数可以在消息中发送给另一个actor,然后由该actor或另一个actor调用。

为了说明起见,对上面显示的代码进行了简化。完整版为Publisher-subscriber关系提供了额外的特性,并使用共享函数使这种关系更加灵活。

例如,通知函数总是被指定为 notify。一个更加灵活的设计将仅仅固定通知的类型,并允许Subscriber选择其共享函数中的任何一个,这些函数在subscribe消息中指定,以代替仅仅包含订阅的actor的消息。

PS:有关详细信息,请参阅完整示例

特别是,假设Subscriber希望避免被锁定到其接口的某个命名方案中。真正重要的是,Publisher可以调用用户选择的某个函数。

shared关键字:

为了允许这种灵活性,actor需要共享一个允许从另一个actor进行远程调用的函数,而不仅仅是对自身的引用。

共享一个函数的能力要求它被预先指定为共享(shared),类型系统强制这些函数遵循这些函数接受、返回和关闭闭包的数据类型的特定规则。

Motoko 允许您省略public*** actor方法的这个关键字,因为无论是否显式标记,public actor的任何public*函数都必须被“共享”。

使用共享函数类型,我们可以扩展上面的例子,使其更加灵活。例如:

type SubscribeMessage = { callback: shared () -> (); };

这个类型与原始类型的不同之处在于,它描述了一个消息记录类型,只有一个名为 callback的字段,上面首先显示的原始类型描述了一个只含有一个名为 notify的方法的actor类型:

type Subscriber = actor { notify : () -> () };

值得注意的是,actor 关键字意味着后一种类型不是包含字段的普通记录,而是包含至少一个“必须名为notify的方法”的 actor。

通过使用 SubscribeMessage 类型,Subscriber actor可以为其 notify方法选择另一个名称:

actor Subscriber {
  var count: Nat = 0;
  public func init() {
    Publisher.subscribe({callback = incr;});
  };
  public func incr() {
    count += 1;
  };
  public query func get(): async Nat {
    count
  };
};

与原始版本相比,唯一更改的行是使用表达式{ callback = incr;}notify 重命名为 incr 并形成新订阅消息有效负载的行。(第四行)

同样地,我们可以更新Publisher以获得一个匹配的接口:

import Array "mo:base/Array";
actor Publisher {
  var subs: [SubscribeMessage] = [];
  public func subscribe(sub: SubscribeMessage) {
    subs := Array.append<SubscribeMessage>(subs, [sub]);
  };
  public func publish() {
    for (sub in subs.vals()) {
      sub.callback();
    };
  };
};
Unknown
- Motoko -
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLMap是一个用于自动化SQL注入的工具,它可以帮助安全测试人员发现和利用Web应用程序中的SQL注入漏洞。要在Windows 10上安装和使用SQLMap,可以按照以下步骤进行操作: 1. 首先,确保你已经安装了Python 2.7版本。如果没有安装,你可以从Python官方网站下载并安装它。 2. 下载SQLMap,可以从官方GitHub页面上获取到最新的SQLMap代码。 3. 解压缩下载的SQLMap文件,并将其放置在Python的安装目录中。 4. 打开命令提示符(CMD),导航到SQLMap所在的目录。 5. 使用以下命令启动SQLMap: ``` python sqlmap.py -h ``` 这将显示SQLMap的帮助信息,包含了可以使用的所有选项和参数。 请注意,在使用SQLMap之前,建议事先了解SQL注入的基本概念和相关技术,以确保你能够正确理解和使用SQLMap工具。同时,使用SQLMap进行安全测试时,务必获得合法的授权,并在符合法律法规的前提下进行测试。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Win10安装SQLMap及报错解决方案](https://blog.csdn.net/Motoko_Lake/article/details/106275510)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [sqlmap启动视频教程](https://download.csdn.net/download/weixin_42859280/10974196)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值