问题 为什么将Perl 6命名参数约束为确定值使其成为必需值?
考虑这些子程序都采用一个命名参数。命名参数应该是可选的,我没有看到任何说法有例外。
没有类型限制,没有问题;命名参数不是必需的。使用可以接受类型对象的类型约束(没有注释, :U
,和 :_
) 没有问题。
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
因为我想要的价值必须定义。
来自 签名 文档:
通常,类型约束仅检查传递的值是否为正确类型。
但是,我没有传递任何价值。我认为这些约束只对作业有关。因为我没有明确地提供一个值来分配我期望没有任务,没有问题。 Rakudo 2017.10的情况并非如此。这导致我以各种令人讨厌的方式解决这个问题。这与我的问题有关 Perl 6块是一个参数还是无参数? 我试图区分零和一个参数的情况。
我可以通过分配默认值来解决这个问题,但在某些情况下,没有默认值是有意义的。一个 Bool
很简单,例如,但是确定的是什么 Int
适合吗?无论它是什么,都会有一些神奇的价值,会使代码变得复杂和分散注意力。我这样做了 Perl 6是否具有Infinite Int 但我逃避了,因为 Inf
在这种情况下,它可以作为有效值。
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();
10374
2018-01-09 10:40
起源
答案:
所有参数总是有一些值,即使它们是可选的。我澄清了你参考的文档 379678 和 b794a7。
可选参数具有默认默认值,它们是显式或隐式类型约束的类型对象(隐式约束为 Any
对于例程和 Mu
对于块)。
sub (Int $a?, Num :$b) { say "\$a is ", $a; say "\$b is ", $b }()
# OUTPUT:
# $a is (Int)
# $b is (Num)
在上面,默认默认值传递参数的类型约束。如果你使用的是同样的情况 :U
要么 :_
类型表情。
但是,当你使用的时候 :D
键入smiley,默认默认值不再与类型约束匹配。如果不加以检查,你将失去指定的好处 :D
约束。例如,默认的默认类型对象会导致此例程的主体爆炸,这需要参数为明确的值。
sub (Int:D $a?, Num:D :$b) { say $a/$b }()
并回答关于是否指定的名义问题 :D
应该自动生成参数。我是-1的想法,因为它引入了一个特殊情况,用户将不得不学习只保存单个字符的输入( !
根据需要标记param)。这样做也会产生一个不太有用的错误,它会讨论arity或required参数,而不是实际问题:参数的类型检查失败的参数的默认默认值。
8
2018-01-09 13:19
FWIW,可选位置参数存在类似问题:
sub a(Int:D $number?) { ... }
a; # Parameter '$number' of routine 'a' must be an object instance of type 'Int', not a type object of type 'Int'. Did you forget a '.new'
如果将类型对象指定为默认值,则会出现同样的问题:
sub a(Int:D $number = Int) { ... };
a; # # Parameter '$number' of routine 'a' must be an object instance of type 'Int', not a type object of type 'Int'. Did you forget a '.new'
我担心这只是后果的结果 :D
应用于参数时的约束:您只需指定一个已定义的默认值,即可在不使用任何参数的情况下调用它。
另一种方法当然可以是使用a multi sub
并且需要命名参数:
multi sub a() { say "no foo named" }
multi sub a(Int:D :$foo!) { say "foo is an Int:D" }
希望这可以帮助
4
2018-01-09 12:35
答案:
所有参数总是有一些值,即使它们是可选的。我澄清了你参考的文档 379678 和 b794a7。
可选参数具有默认默认值,它们是显式或隐式类型约束的类型对象(隐式约束为 Any
对于例程和 Mu
对于块)。
sub (Int $a?, Num :$b) { say "\$a is ", $a; say "\$b is ", $b }()
# OUTPUT:
# $a is (Int)
# $b is (Num)
在上面,默认默认值传递参数的类型约束。如果你使用的是同样的情况 :U
要么 :_
类型表情。
但是,当你使用的时候 :D
键入smiley,默认默认值不再与类型约束匹配。如果不加以检查,你将失去指定的好处 :D
约束。例如,默认的默认类型对象会导致此例程的主体爆炸,这需要参数为明确的值。
sub (Int:D $a?, Num:D :$b) { say $a/$b }()
并回答关于是否指定的名义问题 :D
应该自动生成参数。我是-1的想法,因为它引入了一个特殊情况,用户将不得不学习只保存单个字符的输入( !
根据需要标记param)。这样做也会产生一个不太有用的错误,它会讨论arity或required参数,而不是实际问题:参数的类型检查失败的参数的默认默认值。
8
2018-01-09 13:19
FWIW,可选位置参数存在类似问题:
sub a(Int:D $number?) { ... }
a; # Parameter '$number' of routine 'a' must be an object instance of type 'Int', not a type object of type 'Int'. Did you forget a '.new'
如果将类型对象指定为默认值,则会出现同样的问题:
sub a(Int:D $number = Int) { ... };
a; # # Parameter '$number' of routine 'a' must be an object instance of type 'Int', not a type object of type 'Int'. Did you forget a '.new'
我担心这只是后果的结果 :D
应用于参数时的约束:您只需指定一个已定义的默认值,即可在不使用任何参数的情况下调用它。
另一种方法当然可以是使用a multi sub
并且需要命名参数:
multi sub a() { say "no foo named" }
multi sub a(Int:D :$foo!) { say "foo is an Int:D" }
希望这可以帮助
4
2018-01-09 12:35
我通过检查确切的类型来解决这个问题 Any
或智能匹配我真正想要的那个:
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();
要回答我原来的问题:所有参数都是必需的。这只是他们如何获得价值的问题。它可以通过参数,显式默认值或隐式默认值(基于其类型约束)。
1
2018-01-10 01:44