为什么将 Perl 6 命名参数限制为一个确定的值使其成为必需值? [英] Why does constraining a Perl 6 named parameter to a definite value make it a required value?

查看:39
本文介绍了为什么将 Perl 6 命名参数限制为一个确定的值使其成为必需值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这些都采用单个命名参数的子例程.命名参数应该是可选的,我没有看到任何说明有例外.

Consider these subroutines that all take a single named parameter. Named parameters should be optional and I haven't seen anything to say there are exceptions to that.

没有类型约束就没有问题;命名参数不是必需的.使用可以接受类型对象的类型约束(无注释、:U:_)就没有问题了.

With no type constraints there's no problem; the named parameter is not required. With a type constraint that can accept a type object (no annotation, :U, and :_) there is no problem.

Parameter '$quux' of routine 'quux' must be an object instance of type 'Int', 
not a type object of type 'Int'.  Did you forget a '.new'?
  in sub quux at /Users/brian/Desktop/type.p6 line 16
  in block <unit> at /Users/brian/Desktop/type.p6 line 37

对于需要定义值(用 :D 注释)的类型约束,命名参数不再是可选的.也就是说,对于任何其他定义,我不必提供值.使用 :D 我必须提供一个值.我不想省略 :D 因为必须定义我想要的值.

With a type constraint that requires a defined value (annotated with :D) the named parameter is no longer optional. That is, with any of the other definitions I don't have to supply a value. With a :D I must supply a value. I'd rather not leave out the :D because the value I want must be defined.

来自签名文档:

通常,类型约束只检查传递的值是否是正确的类型.

Normally, a type constraint only checks whether the value passed is of the correct type.

但是,我没有传递任何价值.我认为这些约束只对作业有影响.由于我没有明确提供要分配的值,因此我预计不会有任何分配也没有问题.Rakudo 2017.10 并非如此.这使我以各种令人讨厌的方式解决此问题.这与我的问题有关 Perl 6 块是一个参数还是一个参数? 我试图区分零和一个论证案例.

But, I pass no value. I figured that these constraints would only matter for an assignment. Since I'm not explicitly supplying a value to assign I expected there to be no assignment and no problem. That's not the case with Rakudo 2017.10. This leads me to workaround this in various unsavory ways. This is related to my question Is that one argument or none for a Perl 6 block? where I try to distinguish between zero and one argument cases.

我可以通过分配默认值来解决这个问题,但在某些情况下,没有有意义的默认值.例如,Bool 很简单,但是什么明确的 Int 适合呢?不管它是什么,都会有一些神奇的价值,会使代码复杂化和分散注意力.我已经用 Perl 6 是否有无限 Int 做到了这一点,但我没有这样做,因为 Inf 用作有效值.

I could work around this by assigning a default value, but in some cases there are no default values that make sense. A Bool is easy, for example, but what definite Int would fit? Whatever it is would be some magical value that would complicate and distract the code. I've done this with Does Perl 6 have an Infinite Int but I get away with that because Inf works as a valid value in that case.

sub foo ( :$foo ) {
    put $foo.defined ?? 'foo defined' !! 'foo not defined';
    }

sub bar ( Int :$bar ) {
    put $bar.defined ?? 'bar defined' !! 'bar not defined';
    }

sub baz ( Int:U :$baz ) {
    put $baz.defined ?? 'baz defined' !! 'baz not defined';
    }

sub quux ( Int:D :$quux ) {
    put $quux.defined ?? 'quux defined' !! 'quux not defined';
    }

sub quack ( Int:_ :$quack ) {
    put $quack.defined ?? 'quack defined' !! 'quack not defined';
    }

foo();
foo( foo => 2 );

bar();
bar( bar => 2 );

baz();
baz( baz => Int );

quack();
quack( quack => 2 );

quux( quux => 2 );
quux();

推荐答案

我通过检查类型 Any 或智能匹配我真正想要的类型来解决这个问题:

I solved this by checking for exactly the type Any or smart matching for the one I actually want:

sub f ( :$f where { $^a.^name eq 'Any' or $^a ~~ Int:D } ) {
    put $f.defined ?? "f defined ($f)" !! 'f not defined';
    }

f( f => 5 );
f();

回答我原来的问题:所有参数都是必需的.这只是他们如何获得价值的问题.它可以通过参数、显式默认值或隐式默认值(基于其类型约束).

To answer my original question: all parameters are required. It's merely a matter of how they get values. It can be through an argument, an explicit default, or an implicit default (based from its type constraint).

这篇关于为什么将 Perl 6 命名参数限制为一个确定的值使其成为必需值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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