perl6祝福和新的区别

smi*_*ith 10 oop perl6 raku

class Singleton {
    # We create a lexical variable in the class block that holds our single instance.
    my Singleton $instance = Singleton.bless; # You can add initialization arguments here.
    method new {!!!} # Singleton.new dies.
    method instance { $instance; }
}
Run Code Online (Sandbox Code Playgroud)

我发现上面的代码实现了Singlelton,我想知道Perl6中的bless和new有什么区别?

my Singleton $instance = Singleton.bless; 


my Singleton $instance = Singleton.new; 
Run Code Online (Sandbox Code Playgroud)

Chr*_*oph 8

可以将其bless视为基础架构,而是new(可自定义的)界面的一部分.

如果你看一下实现Mu(类系统的根目录),你会看到bless来电nqp::create,低层次的构造函数,然后调用BUILDALL,其将向继承链调用适当的BUILD(子)方法来初始化宾语.默认new依次只是调用bless.

所以new调用bless电话BUILDALL呼叫BUILD.通常情况下,你应该离开bless,并BUILDALL独自覆盖newBUILD定制.另请注意,名称new只是一种约定:它是一种常规方法,除了调用之外不会做任何特殊操作bless.


Mar*_*rty 5

简单来说,new是一个功能齐全的构造函数,而bless是一个极简主义的构造函数.

引用doco祝福,祝福是......

较低级别的对象构造方法比新的.创建与调用者相同类型的新对象,使用命名参数初始化属性,并返回创建的对象.编写自定义构造函数时可以使用此方法:

class Point {
    has $.x;
    has $.y;
    multi method new($x, $y) {
        self.bless(:$x, :$y);
    }
}
my $p = Point.new(-1, 1);
Run Code Online (Sandbox Code Playgroud)

......而新的是......

构造(创建+初始化)类的新对象的默认方法.此方法仅需要命名参数,然后使用这些参数初始化具有相同名称的访问器的属性.类可以提供自己的新方法来覆盖此默认值.

New触发了一个对象构造机制,该机制在继承层次结构的每个类中调用名为BUILD的子方法(如果存在).有关更多信息,请参阅有关对象构造文档.

请参阅有关对象构造的文档以获取完整的故事,但关键的一点是;

Mu.new调用方法对其调用者进行祝福,传递所有命名参数.bless创建新对象,然后在其上调用方法BUILDALL.BUILDALL以反向方法解析顺序(即从Mu到大多数派生类)遍历所有子类,并在每个类中检查是否存在名为BUILD的方法.如果存在,则调用它,再次将方法new中的所有命名参数传递给它.

在这个答案的早期版本中,我说祝福没有通过调用submethod BUILD的类层次结构 - 如上所述 - 这是错误的. .bless做同样的事情.

那么,你何时使用一个而不是另一个?如果默认.新的类提供是不是你想要的构造函数,你将宣布一个method new在你的类,它会叫.bless构造对象,然后你将着手初始化属性和执行这些其他任务的默认.新不这样做.