在raku中,当不匹配的值时,常规不返回吗?
根据 raku documentation ,常规 first 首先返回 nil
当不匹配值时。但是,为什么行不说($ result === nil);
(下图)打印 true
?
sub MAIN()
{
my @myNumberList is Array[Int] = [2, 2, 5, 7] ;
my $result = @myNumberList.first( {$_ > 10} ) ;
say '$result' ;
say $result ;
say $result.WHAT ;
say ($result === Nil) ;
} # end sub MAIN
程序输出是…
$result
(Any)
(Any)
False
更新
我的目标是确定列表或数组是否包含满足给定谓词的一个或多个元素。在以下示例程序中, elems
例程返回一个大于0的值,并且仅当给定列表或数组中至少包含一个满足相应调用中给出的谓词>
>的谓词GREP
。
sub MAIN()
{
my $myList = (2, 2, 5, 7) ;
say '$myList' ;
say $myList ;
say $myList.WHAT ;
my $grepResult1 = $myList.grep( * > 10, :p ) ;
say '$grepResult1' ;
say $grepResult1 ;
say $grepResult1.WHAT ;
say ($grepResult1.elems <= 0) ;
my $grepResult2 = $myList.grep( * > 4, :p ) ;
say '$grepResult2' ;
say $grepResult2 ;
say $grepResult2.WHAT ;
say ($grepResult2.elems <= 0) ;
my @myArray = [2, 2, 5, 7] ;
say '@myArray' ;
say @myArray ;
say @myArray.WHAT ;
my $grepResult3 = @myArray.grep( * > 10, :p ) ;
say '$grepResult3' ;
say $grepResult3 ;
say $grepResult3.WHAT ;
say ($grepResult3.elems <= 0) ;
} # end sub MAIN
程序输出是…
$myList
(2 2 5 7)
(List)
$grepResult1
()
(Seq)
True
$grepResult2
(2 => 5 3 => 7)
(Seq)
False
@myArray
[2 2 5 7]
(Array)
$grepResult3
()
(Seq)
True
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在“避免陷阱以避免” 文档页面上的有趣问题。请参阅特定的小标题:。另外, nil nil nil 的Raku文档页面。
推测的那样 - 是在右侧 上使用连接 使用智能
简短的答案 - 就像我
可以
匹配 可以简化上述代码(并清理输出)。
.Defined
:for
结果
上面的(其中没有匹配值)SAD SAD SADE $结果,
:如果$ result.defined; 什么都没有返回;
对于
result2
上面(其中第一个匹配值为2)say $ result2如果$ result2.defined;
返回2
。。。 P>要进一步阅读以了解上面发布的SmartMatch解决方案是如何产生的,请查看以下github问题:”通常,~~的左侧不应是自动线程” 。
[此外,((出于混淆读者的危险),请查看以下 raku 代码发布在以下 perl5 文档页面:https://perldoc.perl。 org/perlsyn#差异与raku]。
附录:进行有关'do-something-fly-if定义的'习惯的讨论,请参见Damian Conway的演讲“巨人肩上” ,其中包括他的用户定义
?=
(“分配 - 如果定义”)操作员的代码。Interesting question that appears to be (somewhat) addressed on the "Traps To Avoid" documentation page. See the specific subheading: "Assignment of Nil can produce a different value, usually 'Any' ". Also, the Raku documentation page on class Nil .
The short answer--as near as I can surmise--is to use smartmatching with a Junction on the right-hand-side:
Sample Code:
Returns:
Alternatively, you can simplify the above code (and clean up your output) using
.defined
:for
result
above (where there are no matching values)say $result if $result.defined;
returns nothing;for
result2
above (where the first matching value is 2)say $result2 if $result2.defined;
returns2
.For further reading to understand how the smartmatch solution(s) posted above came about, look at the following Github issue: "In general, the left side of ~~ should not be auto-threading".
[Also, (at the risk of confusing the reader), take a look at the Raku code posted on the following Perl5 doc page: https://perldoc.perl.org/perlsyn#Differences-from-Raku ].
ADDENDUM: For a discussion on the 'do-something-only-if-defined' idiom in Raku, see Damian Conway's talk "On The Shoulders of Giants", which includes his code for a user-defined
?=
("assign-if-defined") operator.tl; dr 是,
first
返回nil
当不匹配的值时。获得想要的一种方法是绑定结果(使用:=
),而不是分配(=
)。一个简单的解决方案
开关从分配运算符(
=
)到(:=
):显示:
原始代码中发生了什么
是的。那不是问题。
nil
表示“缺乏值...”。。因此不要将其视为一个值,例如
42
或'string''< /代码>或空列表²。
将
nil
分配变量将变量的值重置为其默认值:default 变量的默认值是
任何³,所以:
这就是发生的事情在您的原始代码中。
选项
您可以设置
$ result
的默认值为nil
,因此当您分配nil
时,您会得到什么您想要:但这很麻烦。很少需要。
通常,如果要变量到 keep a
nil
,则只是 bind 它而不是分配:只需设置您的心理模型为了匹配Raku的工作,您会发现这都非常简单。footnotes〜
per 其doc ,
nil
是“没有值或良性失败”。如果您调用first
在与谓词匹配的值列表中找到第一个值,则适用“缺乏值”的方面,但没有这样的值。如果您调用首先
,则适用“良性失败”,并且遇到某些错误条件,并且决定其良性,但应该终止其处理,或者抛出一个例外,以使得进一步的评估继续以代码继续,以至于接收由first
返回的值。当您阅读此脚注时,您可能会认为这两种情况最好单独处理。但是,如果您想进一步考虑,希望他们能像同一枚硬币的两个方面一样工作。任何称为代码都可以返回
nil
,并且调用代码知道呼叫的结果是没有值。这可能是由于完全正常的处理,该处理无值,或者是由于遇到错误的处理,但是该错误是由所谓的代码考虑到如此良性,以至于不值得通过返回nil ,或导致抛出的例外,随后处理以清除误差条件 - 从而将处理返回正常状态。 Raku优雅而实用的
nil
是我❤raku的另一个原因。²空列表仍然是一个值。尽管一个空的。
³
任何
都是一种类型。当被视为“值”时,它是 type object代码>任何或子类型。它为变量和参数提供了自然的默认值。⁴我怀疑我写了我的“正义...”句子来冒犯了人们。我想到了删除或编辑它,但是后来人们不会有 @jubilatious1的评论的背景,而我的观点,我认为这是 @jubilatious1被误解的好主意,它会丢失。我现在将此脚注留下来,希望有人认为这是一个问题,并且/或者如果我将其删除是个好主意,或者相反,请与我互动。
TL;DR Yes,
first
returnsNil
when no values match. One way to get what you want is to bind the result (with:=
) instead of assigning it (with=
).A simple solution
Switch from the assignment operator (
=
) to the binding operator (:=
):displays:
What's happening in your original code
Yes. That's not the problem.
Nil
represents "Absence of a value ...".¹So don't think of it as a value like, say,
42
or'string'
or an empty list².Assigning
Nil
to a variable resets the variable's value to its default:The default default value for a variable is
Any
³, so:That's what happened in your original code.
Options
You could set
$result
's default toNil
so that when you assignNil
to it you get what you want:But that's cumbersome. And seldom desirable.
Usually, if you want a variable to keep a
Nil
, you just bind it instead of assigning it:Just set your mental model to match what Raku's doing and you'll find it's all really simple.⁴Footnotes
¹ Per its doc,
Nil
is "Absence of a value or a benign failure". The "Absence of a value" aspect applies if you callfirst
to find the first value in some list of values that matches a predicate, but there were no such values. The "benign failure" applies if you callfirst
and it encounters some error condition and either decides it's benign but ought terminate its processing, or throws an exception that gets handled such that further evaluation continues with the code that receives the value returned byfirst
.As you read this footnote you might think these two cases would best be handled separately. But if you think further you will hopefully see that they work beautifully as two sides of the same coin. Any called code can return
Nil
, and calling code knows that the result of the call is an absence of a value. This may be due to entirely normal processing which yields no value, or due to processing that encountered an error, but that error was either considered by the called code as so benign as to not be worth reporting to the caller other than by returningNil
, or resulted in an exception being thrown that was subsequently handled to clear the error condition -- thus returning processing to normal status. Raku's elegant and practicalNil
is yet another reason why I ❤ Raku.² An empty list is a still a value. Albeit an empty one.
³
Any
is a type. When treated as a "value" it's a type object representing an undefined value of typeAny
or a subtype thereof. It makes a natural default default value for variables and parameters.⁴ I suspect I offended folk by writing my "Just ..." sentence. I thought about deleting or editing it, but then folk wouldn't have context for @jubilatious1's comment and my point, which I think is a good one that @jubilatious1 misunderstood, would be lost. I'm leaving it in with this footnote for now in the hope someone will engage with me if they think it is a problem and/or if it would be a good idea for me to remove it or, conversely, unstrike it.