class Nil is Cool { }

Nil 可用于填充通常会有值的位置,这样做时明确表示没有值。它还可以用作 Failure 的更便宜、更不激烈的替代方案。(事实上,类 Failure 源自 Nil,因此智能匹配 Nil 也将匹配 Failure。)

Nil 与其唯一可能的值 Nil 完全相同。

say Nil === Nil.new;        # OUTPUT: «True␤»

除了 Failure 之外,Nil 及其子类始终可以从例程返回,即使例程指定了特定的返回类型。它也可以在不考虑返回类型是否已定义的情况下返回,但是,Nil 在所有其他目的下都被视为未定义。

sub a--> Int:D ) { return Nil }
a().say;                    # OUTPUT: «Nil␤»

Nil 是从空例程或闭包,或使用空 return 语句的例程返回的。

sub a { }a().say;         # OUTPUT: «Nil␤» 
sub b { return }b().say;  # OUTPUT: «Nil␤» 
say (if 1 { });             # OUTPUT: «Nil␤» 
{ ; }().say;                # OUTPUT: «Nil␤» 
say EVAL "";                # OUTPUT: «Nil␤»

在列表中,Nil 占据一个值的空间。迭代 Nil 的行为与迭代任何不可迭代值的行为相同,产生一个 Nil 序列。(当您需要其他含义时,特殊值 Empty 可用于在插入列表时不占用任何空间,并在迭代时不返回任何值。)

(1Nil3).elems.say;      # OUTPUT: «3␤» 
(for Nil { $_ }).raku.say;  # OUTPUT: «(Nil,)␤»

Nil 的任何不存在的方法的调用,以及因此进行的任何下标操作,都将成功并返回 Nil

say Nil.ITotallyJustMadeThisUp;  # OUTPUT: «Nil␤» 
say (Nil)[100];                  # OUTPUT: «Nil␤» 
say (Nil){100};                  # OUTPUT: «Nil␤»

当分配给 容器 时,Nil 值(但不是 Nil 的任何子类)将尝试将容器还原为其默认值;如果未声明此类默认值,Raku 假设为 Any

由于哈希赋值需要两个元素,因此请使用 Empty,而不是 Nil,例如

my %h = 'a'..'b' Z=> 1..*;
# stuff happens 
%h = Empty# %h = Nil will generate an error

但是,如果容器类型受 :D 约束,则向其分配 Nil 将立即引发异常。(相比之下,实例化的 Failure 匹配 :D,因为它是一个明确的值,但除非碰巧是 Failure 的父类,否则将无法匹配实际的名义类型。)本机类型不能具有默认值,也不能持有类型对象。将 Nil 分配给本机类型容器将导致运行时错误。

my Int $x = 42;
$x = Nil;
$x.say;                     # OUTPUT: «(Int)␤» 
 
sub f--> Int:D ){ Nil };  # this definedness constraint is ignored 
my Int:D $i = f;            # this definedness constraint is not ignored, so throws 
CATCH { default { put .^name''.Str } };
# OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to $y; expected Int but got Any (Any)» 
 
sub g--> Int:D ){ fail "oops" }# this definedness constraint is ignored 
my Any:D $h = g;                   # failure object matches Any:D, so is assigned

但是

my Int:D $j = g;
# It will throw both exceptions: 
# Earlier failure: 
#  oops 
#   in sub g at <unknown file> line 1 
#   in block <unit> at <unknown file> line 1 
# 
# Final error: 
#  Type check failed in assignment to $j; expected Int:D but got Failure (Failure.new(exception...) 
#   in block <unit> at <unknown file> line 1 

由于未类型化的变量是类型 Any,因此向其分配 Nil 将导致 (Any) 类型对象。

my $x = Nil;
$x.say;          # OUTPUT: «(Any)␤» 
my Int $y = $x;  # will throw an exception 
CATCH { default { put .^name''.Str } };
# OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to $y; expected Int but got Any (Any)␤»

如果您正在寻找一个变量,当该变量出现在右侧时将对象转换为类型对象,则可以将容器类型化为 Nil

my Nil $x;
my Str $s = $x;
$s.say;          # OUTPUT: «(Str)␤»

此转换为类型对象规则有一个重要的例外:将 Nil 分配给具有默认值的变量将恢复该默认值。

my Int $x is default(42= -1;
my $y = 1;
for $x$y -> $val is rw { $val = Nil unless $val > 0 }
$x.say;          # OUTPUT: «42␤»

诸如 BIND-POSASSIGN-KEYASSIGN-POS 等方法将失效;BIND-KEY 将产生一个带有 X::Bind 异常的故障,而 STORE 将产生一个 X::Assignment::RO 异常。

方法§

方法 append§

method append(*@)

警告用户他们尝试附加到一个 Nil(或派生类型对象)。

方法 gist§

method gist(--> Str:D)

返回 "Nil"

方法 Str§

method Str()

警告用户他们尝试将一个 Nil 字符串化。

方法 new§

method new(*@)

返回 Nil

方法 prepend§

method prepend(*@)

警告用户他们尝试预置到一个 Nil 或派生类型对象。

方法 push§

method push(*@)

警告用户他们尝试推送到一个 Nil 或派生类型对象。

方法 unshift§

method unshift(*@)

警告用户他们尝试前置到一个 Nil 或派生类型对象。

方法 ords§

返回一个空的 Seq,但也会根据其使用的上下文发出警告(例如,如果与 say 一起使用,则会发出有关在字符串上下文中使用它的警告)。

方法 chrs§

将返回 \0,并抛出警告。

方法 FALLBACK§

method FALLBACK(| --> Nil{}

备用方法接受任何参数,并始终返回一个 Nil

方法 Numeric§

method Numeric()

警告用户他们尝试将一个 Nil 数字化。

类型图§

Nil 的类型关系
raku-type-graph Nil Nil Cool Cool Nil->Cool Mu Mu Any Any Any->Mu Cool->Any Failure Failure Failure->Nil

展开上面的图表