Q04:自定义类型和链接列表

Custom type and Linked list

Custom type 自定义类型

以前程序操作了不同的类型(Nat、Text、Bool、Array); 现在可创造自己定义的类型:

module {

}

这是一个模块声明,与之前所有作为actor声明的 .mo 文件相反。

模块(就像以前一直使用的基础库模块一样)是程序可以导入和重用的一段代码。


这就是创建自定义类型的方法。 如果程序希望可以从模块外部访问程序里的类型,则需要将其公开。

public type Person = {
  name : Text;
  age : Nat;
};

Person 类型也称为具有不同字段(姓名、年龄)的object对象。


现在程序已经声明了类型,可创建第一个 Person 类型的变量。

let tom : Person = {
  name = "Tom Cruise";
  age = 59;
};

程序可以使用点符号访问任何字段。

let tom_name = tom.name;
let tom_age = tom.age;

In your main.mo file you can import the type Person and use it as if it was part of Motoko native types.

import Person "person";
actor {
  public type Person = Person.Person;
  let penelope : Person = {
    name = "Penelope Cruz";
    age = 47;
  };

};

💡 Person.Person simply means : grab the type Person from the Person module.


Linked list 

A linked list is a datastructure, that contrary to array has a dynamic size. It consists of many nodes each node contains :

  • A value of type T.
  • A pointer to the next node or to null.

A linked list of Nat

The first element of this linked list is a node where :

  • Value of type Nat equals to 12.
  • A pointer to next node.

💡 A pointer is just a memory location indicating where a data is stored. You can think of it as an arrow indicating where to find the next node.

Here's how one would define a linked list in Motoko.

public type List<T> = ?(T, List<T>);

This means that a List of type T is either :

  • null
  • couple of two elements.
    • 1st element is a value of type T.
    • 2nd element is a List of type T.

💡 To acces an element in a linked list you need to start from the first node and follow all the nodes until you came accross the value you are looking for.
This is more complex than with arrays where we could just use array[i], but linked lists have other advantages that we will see.

Switch / Case

We have already seen the switch/case expression in previous lessons, but let's make a quick review. We can use the switch/case on optional expression. An element of type List can be of value null. We can check it that way.

public type List<T> = ?(T, List<T>);
public func is_list_null(list : List<Nat>) : async Text {
        switch(list){
            case(null) {
                return "The list is null... 😢"
            };
            case(?list){
                return "This list is not null 🥳"
            };
        }
    };

The switch/case can also be used for testing different values.

public func month_to_season (month : Text) : async Text {
  switch(month){
    case("January") return "Winter";
    case("February") return "Winter";
    case("March") return "Spring";
    case("April") return "Spring";
    case("May") return "Spring";
    case("June") return "Summer";
    case("July") return "Summer";
    case("August") return "Summer";
    case("September") return "Autumn";
    case("October") return "Autumn";
    case("November") return "Autumn";
    case("December") return "Winter";
    case(_) return "This is not a month";
  }
};

The last case statement is used to indicate a default value, in case the value in the switch (in our case the month) do not find in any of the previous cases. It will default to the case with the _ indicator :

case(_) return "This is not a month";

You can actually try this function by deploying it in the Motoko Playground and check what value you get back with "April" and then with "Hello".

Q04:自定义类型和链接列表
arkMeta Crypto Network Limited, arkSong 2023年10月31日
标签
登录 留下评论

Q03:数组、Option和通用类型以及高阶函数
Array, Optional and Generic type, and Higher order functions.