Raku如何处理钻石问题?

问题描述 投票:1回答:1

所以Raku具有多重继承已经不是什么秘密了,这让我感到奇怪:“ Raku如何以任何合理的方式处理它?”

一些初步测试表明,默认行为是从继承列表中的first类继承的,很好,许多其他语言也都这样做了

class A {
    has $.foo = 0;

    method speak {...}
}

class B is A {
    has $.foo = 1;

    method speak {
        say 'moo';
    }
}

class C is A {
    has $.foo = 2;

    method speak {
        say 'baa';
    }
}

class D is B is C {}

class E is C is B {}

say D.new.foo; # prints 1 (from B)
say E.new.foo; # prints 2 (from C)

但是那让我想知道,如果我想让D使用Cspeak,该怎么办?由于继承顺序,默认情况下我得到B。

我了解通过简化歧义机制可以解决确切的问题,但是假设我处于一种我无法支配角色的情况(老板讨厌他们,继承了一个没有图书馆的图书馆)它们,选择借口),确实需要消除继承的类的歧义。

Raku中处理它的机制是什么?

multiple-inheritance raku diamond-problem
1个回答
1
投票

通常,您需要在具有(潜在)歧义性的类中提供平局决胜局方法。幸运的是,您不必创建单独的方法,因为可以在调用中调用方法的特定版本。

因此,您的问题的答案:向类D添加方法speak,并从类speak中调用该方法C

class D {
    ...
    method speak { self.C::speak }
}

现在,这将导致一些开销,因为您将具有额外的间接级别。如果发现这是性能问题,可以执行一些元编程,以将speak中的D方法别名为speak中的C方法:

class D {
    ...
    BEGIN D.^add_method("speak",C.^find_method("speak"));
}

由于BEGIN,这将在编译时将Method对象添加到名为Dspeak类中,该对象由类speakC方法定义。

© www.soinside.com 2019 - 2024. All rights reserved.