我遇到了这个 JS 代码片段:
function append(demo = "", file = "") {
const extra = "ctl=1&embed=1";
if (demo && file) return `/${demo}/?file=${file}&${extra}`;
if (!demo && file) return `/?file=${file}&${extra}`;
if (demo && !file) return `/${demo}&${extra}`;
return `?${extra}`;
}
我可以使用
if
s 轻松地将它移植到 Raku,但我认为使用 given
/when
将是展示该功能的好方法。我想出了以下几点:
sub append(Str :$demo, Str :$file) {
my $extra = "ctl=1&embed=1";
given ($demo, $file) {
when $demo.so, $file.so { "/$demo/?file=$file&$extra" }
when $demo.not, $file.so { "/?file=$file&$extra" }
when $demo.so, $file.not { "/$demo?$extra" }
default { "?$extra" }
}
}
say append :file("here"), :demo("there"); # /there/?file=here&ctl=1&embed=1
say append :file("here"); # /?file=here&ctl=1&embed=1
say append :demo("here"); # /here?ctl=1&embed=1
say append; # ?ctl=1&embed=1
但是它非常重复,我什至不确定它是否是惯用的 Raku 所以我想我可以做以下事情:
sub append(Str :$demo = '', Str :$file = '') {
my $extra = "ctl=1&embed=1";
given ($demo.so, $file.so) {
when (True, True) { "/$demo/?file=$file&$extra" }
when (False, True) { "/?file=$file&$extra" }
when (True, False) { "/$demo?$extra" }
default { "?$extra" }
}
}
但这并不像预期的那样工作。因此,是否有可能将值列表绑定到主题变量
$_
并使用 when
s 对其进行智能匹配?我(错误)记得 Daniel“codesections”Sockwell 在这种程度上做了一些事情,但我不记得在哪里。
我运行了你的代码并得到了这个错误:
Use of uninitialized value of type Str in string context.
Methods .^name, .raku, .gist, or .say can be used to stringify it to something meaningful.
您可以像这样在 append() 签名中添加默认值来初始化参数值:
sub append(Str :$demo='', Str :$file='') {
哦,不需要
do given
,简单的given
就可以了。
我想出了以下内容
这是巧合。你使用 smartmatch 对抗
True
在这种情况下你不需要给出:
sub append(Str :$demo, Str :$file, :$extra = "ctl=1&embed=1") {
when $demo.so & $file.so { "/$demo/?file=$file&$extra" }
when $file.so { "/?file=$file&$extra" }
when $demo.so { "/$demo?$extra" }
default { "?$extra" }
}
我可以将值列表绑定到主题变量 $_ 并使用 whens 对其进行智能匹配吗?
是的,你可以:
sub append(Str :$demo, Str :$file, :$extra = "ctl=1&embed=1") {
given ($demo, $file) {
when :so , :so { "/$demo/?file=$file&$extra" }
when :!so, :so { "/?file=$file&$extra" }
when :so , :!so { "/$demo?$extra" }
default { "?$extra" }
}
}
您可以使用smartmatch对抗
Siganture
:
sub append(|c (Str :$demo, Str :$file)) {
my $extra = "ctl=1&embed=1";
given c {
when :(:demo($)!, :file($)!) { "/$demo/?file=$file&$extra" }
when :(:file($)!) { "/?file=$file&$extra" }
when :(:demo($)!) { "/$demo?$extra" }
default { "?$extra" }
}
}
但是使用multidispath
更有趣constant $extra = 'ctl=1&embed=1';
proto append (Str :$demo,Str :$file) {*}
multi append (:$demo!, :$file!) { "/$demo/?file=$file&$extra" }
multi append (:$file!) { "/?file=$file&$extra" }
multi append (:$demo!) { "/$demo?$extra" }
multi append () { "?$extra" }