[英]What is the meaning of (Any) in Raku - specifically the ()?
这是一个 Raku 的实验:
> my $x
(Any)
> my $y=1
1
> my @a=[1, 2]
[1 2]
> my %h=a=>'b'
{a => b}
> say "nil" unless $x
nil
我可以看到[]
表示数组文字, {}
表示 hash 文字。
我还可以看到(Any)
的行为类似于 nil - 在上面显示的 boolean 上下文中返回 false。
我觉得(Any)
很有趣。 文档告诉我Any
只是 Raku 中的神类之一。 但是Any
周围的括号()
告诉我什么?
当您使用 REPL 时,表达式的结果使用say
显示。 say
function 在表达式上调用.gist
function。
Any
是一个类型对象。 类型对象有一个.gist
方法,可以在它们周围加上括号。
put
function 与say
function 几乎相同,但它在表达式上调用了.Str
function。 这会产生一个警告,因为您不能真正对 object 类型进行字符串化。 观察差异:
$ raku -e 'say Any'
(Any)
# raku -e 'put Any'
Use of uninitialized value of type Any in string context.
Methods .^name, .raku, .gist, or .say can be used to stringify it to something meaningful.
in block <unit> at -e line 1
除了 lizmat 的出色答案之外,解释这里发生的事情可能与此相关。
当你说my $foo
时,你实际上是在说my Any $foo
。 1当你说my @foo
时,你隐含地在说更接近my Any @foo
的东西,它与my Array[Any] $foo
相同(但在位置容器中)。 这使您可以将任何内容放入数组中,因为它的类型是Any
。
当您访问一个未定义的 object 时,它会返回一个未定义的值——但该值仍然是输入的。 只是碰巧默认情况下,类型是Any
。 然而,我们可以改变一些东西,它可能会变得更清楚:
my Str $foo;
say $foo; # a Str that's undefined, so '(Str)';
my $bar; # implicitly typed Any
say $bar; # an Any that's undefined, so '(Any)';
my Int @foo = 0, 1, 2;
say @foo[0]; # an Int defined as 0, so '0'
say @foo[1]; # an Int defined as 1, so '1'
say @foo[3]; # an Int that's undefined, so '(Int)'
正如 lizmat 在她的回答中指出的那样, (Type)
是.gist
方法的默认表示,该方法由.say
用于未定义的值。 2
他们不返回Nil
的原因是,根据定义, Nil
会为调用它的每个方法返回Nil
(有一些例外,例如Bool
会返回False
)——这有点像 Objective-C 的nil
。 但是未定义的类型 object 仍然有用途:例如,您仍然可以在其上调用方法,只要它们不访问属性。 有时这可能是一个非常有用的属性,它实际上使您能够执行以下操作:
my Foo $foo .= new;
哪个是语法糖
my Foo $foo;
$foo = $foo.new;
$foo
是一个未定义的类型 object,所以我们实际上仍然调用Foo.new
。
有一个非常简单的答案。
Any
是 class。 具体来说,它是所有其他 class 的默认基础 class。
在 Raku 中,您可以像传递实例一样传递 class。
my $a = 1;
my $b = $a.WHAT;
say $b;
# (Int)
问题是,如果您尝试使用 class 就好像它是一个实例一样,就会发生不好的事情。
say $b + 4;
# ERROR: … must be an object instance of type 'Int', not a type object of type 'Int'.
当您使用 REPL 时,它会自动调用.gist
并打印结果。
.gist
旨在让人类能够理解价值是什么。
那么为什么要在 class 的名称周围加上括号呢?
对我来说,这样做是为了告诉您它不是Str
或其他实例。
say 'Str'; # say calls .gist
# Str
say 'abc'.WHAT;
# (Str)
say 'abc'.WHAT.^name;
# Str
say 'abc'.^name;
# Str
除了其中一个之外,所有这些都是Str
class 的一个实例。
(猜猜是哪一个。)
基本上,括号会告诉您尝试将其用作实例是错误的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.