【问题标题】:What is the meaning of (Any) in Raku - specifically the ()?Raku 中的 (Any) 是什么意思 - 特别是 ()?
【发布时间】:2020-05-15 11:32:20
【问题描述】:

这是一个 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 周围的括号() 告诉我什么?

【问题讨论】:

    标签: raku


    【解决方案1】:

    当您使用 REPL 时,表达式的结果显示为使用 saysay 函数在表达式上调用 .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 ObjectsType SystemType Objects 了解更多信息。

    【讨论】:

    • 但确实,对于新手来说,它可能看起来像一个单元素列表。也许我们将来可以改变什么?
    • 但这是 Raku 中的一个普遍“问题”:(foo) 不是一个元素列表,它只是一组东西。 (foo,)(注意逗号)一个元素列表。
    • 对于一个新人来说,只是(Nil) 或类似的人会更期待。 () 很重要,可以将其与 REPL 中未引用的字符串 'Nil' 区分开来。
    • jjmerelo:如果有任何改变,我推荐(Type:U)Type:U,尽管最终(Type) 只是一个需要学习的习语。遗憾的是,您无法覆盖/包装 Mu 的要点并让它自动为其他所有内容工作 - 让模块将对象键入为 Type 但绿色/灰色/黄色等等可能有点酷。
    • 我已经为此开始了一个问题解决票:github.com/Raku/problem-solving/issues/194
    【解决方案2】:

    有一个非常简单的答案。

    Any 是一个类。具体来说,它是所有其他类的默认基类。

    在 Raku 中,您可以像传递实例一样传递类。

    my $a = 1;
    my $b = $a.WHAT;
    
    say $b;
    # (Int)
    

    问题是,如果您尝试将类当作实例来使用,就会发生不好的事情。

    say $b + 4;
    # ERROR: … must be an object instance of type 'Int', not a type object of type 'Int'.
    

    当您使用 REPL 时,它会自动调用 .gist 并打印结果。

    .gist 旨在让人类能够理解其价值。

    那么为什么要在类名周围加上括号呢?

    这样做是为了告诉你它不是Str 或其他实例,这对我来说是有道理的。

    say 'Str'; # say calls .gist
    # Str
    
    say 'abc'.WHAT;
    # (Str)
    
    say 'abc'.WHAT.^name;
    # Str
    
    say 'abc'.^name;
    # Str
    

    除了其中一个之外,所有这些都是Str 类的实例。
    (猜猜是哪一个。)


    基本上,括号会告诉您尝试将其用作实例是错误的。

    【讨论】:

    • 谢谢布拉德。这个答案很有帮助,因为它指出了对象实例和类型对象之间的区别。而且总结句也很有用。
    【解决方案3】:

    除了 lizmat 的出色答案之外,解释这里发生的事情可能与此相关。

    当你说 my $foo 时,你实际上是在说 my Any $foo1 当你说 my @foo 时,你是在隐含地说更接近 my Any @foo 的东西,这是一样的作为my Array[Any] $foo(但在位置容器中)。这使您可以将任何内容放入数组中,因为它的类型是Any

    当您访问一个未定义的对象时,它会返回一个未定义的值——但该值仍然是类型化的。只是碰巧默认情况下,类型是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。但是未定义的类型对象仍然有用途:例如,您仍然可以在其上调用方法,只要它们不访问属性。有时这可能是一个非常有用的属性,它实际上使您能够执行以下操作:

      my Foo $foo .= new;
    

    什么是语法糖

      my Foo $foo;
      $foo = $foo.new;
    

    $foo 是一个未定义类型的对象,所以我们实际上还是调用了Foo.new


    1. 正如 raiph 在 cmets 中正确指出的那样,我应该注意到这不是 确切正在发生的事情,但从最终用户的角度来看,这已经足够接近并且不那么复杂了。李>
    2. 人们总是可以覆盖它,我已经为我的一些类做了这个,这些类的名称可疑地接近或与添加明确前缀的内置函数相同,因此我不会混淆它们。

    【讨论】:

    • 谢谢@user0721090601。所有这些都是有帮助的。对我来说缺少的部分是 (Any)gist 是它表现为一个未定义的值,但 .gist 并没有告诉我 my $x; 没有价值。像(Any[nil]) 这样的东西会很好。
    • Ross Attrill:我能理解。这只是乐开发的习俗之一。一旦你明白 (Type) 的意思是“类型类型的未定义值”) 你就会习惯它。也许可以将:U 添加为(Any:U),它明确地是一个未定义的值/类型对象。我试着看看我是否可以在一个模块中完成它,但是由于某种原因包装现有方法不起作用=\
    • 其实,你可以使用Mu.^find_method('gist').wrap( method { self.defined ?? (callsame) !! ( (callsame).substr(0,*-1) ~ ':U)') } );,但不幸的是,大多数内置类都明确定义了它们的要点(它可能会节省一点方法解析)
    • 这可能是编译时方法缓存的影响。事实上,Raku 的班级知道他们的父母,但父母不知道他们的孩子。
    • .oO (“当你说my $foo时,你是在含蓄地说my Any $foo。”对此我说,“当意识的钟声敲响它甜美的音调时,pedagogical facilitations是谎言重量在他们的范围内,所以在智慧的尽头,真相响起;首先响起的是苏格拉底的怀疑。”或者,更平淡地说,当一个人写my $foo时,你隐含地写my Mu $foo is default(Any)。这是相当合理的离开作为脚注。这反过来表明这属于阶梯的第一级。这反过来表明这是一个谎言。“等等。什么?”)
    猜你喜欢
    • 1970-01-01
    • 2012-11-10
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 2017-06-11
    • 2018-03-05
    • 2023-03-27
    相关资源
    最近更新 更多