Raku 中的 (Any) 是什么意思 - 特别是 ()?
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
我可以看到 []
表示数组文字,{}
表示哈希文字。
我还可以看到 (Any)
的行为类似于 nil - 在上面显示的布尔上下文中返回 false。
我觉得 (Any)
很有趣。文档告诉我 Any
只是 Raku 中的一位神 类。但是 Any
周围的括号 ()
告诉我什么?
当您使用 REPL 时,表达式的结果使用 say
显示。 say
函数调用表达式上的 .gist
函数。
Any
是类型对象。类型对象有一个 .gist
方法,可以在它们两边加上括号。
put
函数与say
函数几乎相同,只是它在表达式上调用了.Str
函数。这会产生警告,因为您无法真正将类型对象字符串化。观察差异:
$ 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
有关详细信息,请参阅 Classes and Objects, Type System, Type Objects。
除了 lizmat 的出色回答之外,解释这里发生的事情可能也很重要。
当你说 my $foo
时,你实际上是在说 my Any $foo
。1 而当你说 my @foo
时,你实际上是在说 my Any $foo
。说一些更接近 my Any @foo
的东西,它与 my Array[Any] $foo
相同(但在位置容器中)。这使您可以将任何内容放入数组中,因为它的类型是 Any
。
当您访问一个未定义的对象时,它 return 是一个未定义的值 — 但该值仍然是类型化的。恰好默认情况下,类型是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
他们不 return Nil
的原因是因为根据定义,Nil
returns Nil
对于调用它的每个方法(除了少数例外,例如 Bool
,其中 return 是 False
)——它有点像 Objective-C 的 nil
。但是未定义的类型对象仍然有用途:例如,只要它们不访问属性,您仍然可以调用它的方法。有时这可能非常有用 属性,它实际上使您能够执行以下操作:
my Foo $foo .= new;
这是
的语法糖
my Foo $foo;
$foo = $foo.new;
$foo
是一个未定义的类型对象,所以我们实际上还是调用了Foo.new
.
- 正如 raiph 在评论中正确指出的那样,我应该注意到这并不是 确切地 正在发生的事情,但从最终用户的角度来看,已经足够接近了没那么复杂。
- 人们总是可以覆盖它,我已经为我的一些 类 做到了,这些名字可疑地接近或相同于添加明确前缀的内置函数,这样我就不会混淆它们.
答案很简单。
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.
的实例
(猜猜是哪一个。)
基本上 parens 告诉您尝试将其用作实例是错误的。
这是 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
我可以看到 []
表示数组文字,{}
表示哈希文字。
我还可以看到 (Any)
的行为类似于 nil - 在上面显示的布尔上下文中返回 false。
我觉得 (Any)
很有趣。文档告诉我 Any
只是 Raku 中的一位神 类。但是 Any
周围的括号 ()
告诉我什么?
当您使用 REPL 时,表达式的结果使用 say
显示。 say
函数调用表达式上的 .gist
函数。
Any
是类型对象。类型对象有一个 .gist
方法,可以在它们两边加上括号。
put
函数与say
函数几乎相同,只是它在表达式上调用了.Str
函数。这会产生警告,因为您无法真正将类型对象字符串化。观察差异:
$ 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
有关详细信息,请参阅 Classes and Objects, Type System, Type Objects。
除了 lizmat 的出色回答之外,解释这里发生的事情可能也很重要。
当你说 my $foo
时,你实际上是在说 my Any $foo
。1 而当你说 my @foo
时,你实际上是在说 my Any $foo
。说一些更接近 my Any @foo
的东西,它与 my Array[Any] $foo
相同(但在位置容器中)。这使您可以将任何内容放入数组中,因为它的类型是 Any
。
当您访问一个未定义的对象时,它 return 是一个未定义的值 — 但该值仍然是类型化的。恰好默认情况下,类型是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
他们不 return Nil
的原因是因为根据定义,Nil
returns Nil
对于调用它的每个方法(除了少数例外,例如 Bool
,其中 return 是 False
)——它有点像 Objective-C 的 nil
。但是未定义的类型对象仍然有用途:例如,只要它们不访问属性,您仍然可以调用它的方法。有时这可能非常有用 属性,它实际上使您能够执行以下操作:
my Foo $foo .= new;
这是
的语法糖 my Foo $foo;
$foo = $foo.new;
$foo
是一个未定义的类型对象,所以我们实际上还是调用了Foo.new
.
- 正如 raiph 在评论中正确指出的那样,我应该注意到这并不是 确切地 正在发生的事情,但从最终用户的角度来看,已经足够接近了没那么复杂。
- 人们总是可以覆盖它,我已经为我的一些 类 做到了,这些名字可疑地接近或相同于添加明确前缀的内置函数,这样我就不会混淆它们.
答案很简单。
Any
是一个 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.
的实例
(猜猜是哪一个。)
基本上 parens 告诉您尝试将其用作实例是错误的。