如何防止Nil将容器还原为默认值? [英] How to keep Nil from reverting container to its default value?

查看:99
本文介绍了如何防止Nil将容器还原为默认值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现一个简单的链接列表,并表示没有下一个节点,我使用的值是 Nil 。问题是,当分配给容器时, Nil 会尝试将容器恢复为其默认值,这意味着我需要使用容器的默认值或任何来确定链接列表的末尾是否已到达。但是,我仍然想使用 Nil (如果仅出于其明确意图),并且没有其他值可以测试代码中下一个节点的不存在(例如,直到$ current ===任何最后,如果$ current-node ===任何; )。在某些情况下:

I'm implementing a simple linked list and to denote the fact that there is no next node, I'm using the value Nil. The thing is that when assigned to a container, Nil will attempt to revert the container to its default value which means I need to use the container's default value or Any to determine if the linked list's end has been reached. However, I'd still like to use Nil (if only for its clear intent) and no other value to test for the non-existence of a next node in the code (e.g., until $current === Any, last if $current-node === Any;). For some context:

class Node {
    has $.data is rw is required;
    has $.next is rw = Nil;
}

class UnorderedList {
    has $!head = Nil;
    
    method add(\item --> Nil) {
        my $temp = Node.new: data => item;
        $temp.next = $!head;
        $!head = $temp;
    }

    method size(--> UInt) {
        my $current = $!head;
        my UInt $count = 0;
        
        until $current === Any {          # <=== HERE
            $count += 1;
            $current .= next;
        }
        
        return $count;
    }
   
    method gist(--> Str) {
        my $current-node = $!head;
        my $items := gather loop {
            last if $current-node === Any; # <=== HERE
            take $current-node.data;
            $current-node .= next;
        }
        
        $items.join(', ')
    }
}


推荐答案

这有点像问使用雨伞时我的头上怎么还会下雨。 :-) Raku中存在 Nil 的主要原因是要提供一个值,该值可以在软失败产生结果时返回该函数,如果将其赋值给任何函数,这将是安全的

This is a bit like asking "how can I still have rain fall on my head while using an umbrella". :-) The primary reason Nil exists in Raku is to provide a value that a function can return on a soft failure to produce a result, which will be safe if assigned into any container that supports being undefined (or defaulted).

因此,可以编写一个函数 func 并返回 Nil ,它将对呼叫者 my SomeType $ foo = func()或呼叫者 my起作用OtherType $ bar = func()

Thus, one can write a function func that can return Nil, and it will Just Work for a caller my SomeType $foo = func() or for a caller my OtherType $bar = func().

虽然有是默认值(无)技巧,我强烈建议您使用其他一些值作为您的标记。在您不希望语言功能提供主要行为的情况下尝试使用语言功能通常会无法顺利进行。

While there is the is default(Nil) trick, I'd strongly suggest using some other value as your sentinel. Trying to use a language feature in a situation where you don't want the primary behavior it exists to provide will generally not go smoothly.

Node 类型对象本身将是一个合理的选择。因此:

The Node type object itself would be a reasonable choice. Thus this:

has $!head = Nil;

成为:

has Node $!head;

然后测试变为:

until $current === Node {

不过,我可能将其写为:

However, I'd probably write it as:

while $current.defined {

code>节点。另一方面,如果我知道 Node 是我的类的实现细节,我将感到足够安全,可以使用依赖于默认布尔化语义来消除混乱: / p>

Which also supports subclassing of Node. On the other hand, if I know Node is an implementation detail of my class, I'd feel safe enough to use rely on the default boolification semantics to remove the clutter:

while $current {

同时,

last if $current-node === Any;

可能会变成:

last without $current-node;

。方法:

last unless $current-node;

最后,如果 Node 只是一个实现细节,我d将其移动到 UnorderedList 内,并使其成为 my 的作用域。

Finally, if Node is just an implementation detail, I'd move it inside UnorderedList and make it my scoped.

这篇关于如何防止Nil将容器还原为默认值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆