当前位置: 首页 > 知识库问答 >
问题:

使用捕获的类型键入类的属性

萧光华
2023-03-14

我遵循了关于在Perl 6中如何使类变为参数化的SO问题的答案中的说明?。然而,我遇到了一些软路障;我试图使用类型捕获键入内部类的属性,并出现以下错误:

Died with X::TypeCheck::Assignment
  in submethod BUILDALL at ...
  in method insert at ...
  in block <unit> at ...

在下面的示例中,我键入了类BinaryNode's$。项属性(带有T),但这样做会导致上述错误:

class BinarySearchTree {
    my role BTSImpl[::T] {
        my class BinaryNode is rw {
            has T $.item; 
            has BinaryNode $.left;
            has BinaryNode $.right;
        }

        method create-node( T $x ) {
            BinaryNode.new(item => $x)
        }
    }

    method ^parameterize(Mu:U \this, Mu \T) {
        my $type := this.^mixin: BTSImpl[T];
        $type.^set_name: this.^name ~ '[' ~ T.^name ~ ']';
        $type
    }
}

my $bst = BinarySearchTree[Int].new;
$bst.create-node(6);

共有1个答案

扈运浩
2023-03-14

首先,几乎不需要执行^参数角色技巧。它出现在一些内部,因为它有助于处理一些无融资创业问题(根据本身定义语言时的那种乐趣)。然而,在普通的Raku代码中,只需编写一个参数化的角色而不是。从消费者的角度来看,通常没有区别;人们可以:

  • 调用<代码>。在其上新建一个实例(实际上在幕后创建一个类,称为“双关语”,并创建该类的实例)
  • 事实上,对类型对象调用任何方法都会得到相同的结果<代码>新的并不特别
  • 从它继承(同样,它在自动生成的类上工作)

还有一个额外的好处,就是有人也可以编写它,而不是继承。

其次,在<代码>角色<代码>内部定义的<代码>类<代码>和封装的<代码>角色<代码>之间没有关系(这是一个一般原则:一个包嵌套在另一个包中并不意味着它们在对象模型级别上有任何关系)。因此,我们需要将其单独泛化并实例化。

这两个因素让我们:

role BinarySearchTree[::T] {
    my role BinaryNode[::T] is rw {
        has T $.item;
        has BinaryNode $.left;
        has BinaryNode $.right;
    }

    method create-node( T $x ) {
        BinaryNode[T].new(item => $x)
    }
}

my $bst = BinarySearchTree[Int].new;
$bst.create-node(6);

这确实应该可以工作,但编译器似乎在二进制节点上的计时错误。我们可以通过强制它将参数化延迟到运行时来解决这个问题;有很多方法可以做到这一点,但编写的二进制节点(BinaryNode)[$(T)]紧凑且便宜(优化后几乎没有额外成本)。从而给出一个有效的解决方案:

role BinarySearchTree[::T] {
    my role BinaryNode[::T] is rw {
        has T $.item;
        has BinaryNode $.left;
        has BinaryNode $.right;
    }

    method create-node( T $x ) {
        BinaryNode[$(T)].new(item => $x)
    }
}

my $bst = BinarySearchTree[Int].new;
$bst.create-node(6);
 类似资料:
  • 我正在尝试获取一些类属性的类型,以便强烈键入我的静态编程语言代码。在打字稿中,我们可以这样做(愚蠢的例子,但这是为了解释) 这样做的好处是,如果我需要更改“_prop”的类型,不需要重构整个代码,因为类型是通过< code>Test["_prop"]找到的。在科特林有办法做到这一点吗? 我在Kotlin中见过反射函数,但无法得到我想要的 科特林代码:

  • 问题 你想自动记录一个类中属性和方法定义的顺序, 然后可以利用它来做很多操作(比如序列化、映射到数据库等等)。 解决方案 利用元类可以很容易的捕获类的定义信息。下面是一个例子,使用了一个OrderedDict来记录描述器的定义顺序: from collections import OrderedDict # A set of descriptors for various types class

  • LineSeries['areaStyle']的类型是AreaStyle | undefined 报错:类型“AreaStyle | undefined”上不存在属性“color”。 如何通过 LineSeries使用color属性的类型呢?

  • 问题内容: 有没有一种方法可以使用嘲笑ArgumentCaptore捕获特定类型的列表。这不起作用: 问题答案: 可以使用@Captor注释避免嵌套的泛型问题:

  • 当我们创建一个类型类时,通常会假设它的函数必须服从某些属性。因此,我们得到了它们各自类型类的么半群和么单律。但是,如果有某种规律,比如结合性,我想要指定多个类可以服从,也可以不服从这个规律,那该怎么办?在Haskell的类型系统中有办法做到这一点吗?这种类型类对类型类的想法在实践中是否可行? 下面是代数中一个很有启发性的例子:

  • 我有以下带有父类的结构,几个子类,每个子类都有自己的枚举和各种键。父类需要具有具有以枚举为特征的键的映射,但枚举类型是抽象的 - 它由实例化的子类确定。 我想使用泛型类型来要求Enum类型来自该特定类 - 因此您只能将APPLE添加到水果中,将芹菜添加到蔬菜中,反之亦然。我的应用程序还要求任何 Food 对象能够查询其可能的类型(例如,打印出所有可能的类型,而不仅仅是我们在 Map 中的类型)。