我想创建一个脚本,它需要一个输入文件和一个可选的输出文件。当您不传递输出文件时,脚本将使用与输入相同的文件名,但扩展名已更改。我不知道如何编写更改扩展名的默认参数。
#!/usr/bin/env raku
unit sub MAIN(
Str $input where *.IO.f, #= input file
Str $output = $input.IO.extension("txt"), #= output file
Bool :$copy, #= copy file
Bool :$move, #= move file
);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用:
No such method 'IO' for invocant of type 'VMNull'
in block <unit> at ./copy.raku line 5
Run Code Online (Sandbox Code Playgroud)
我怎样才能做这样的事情呢?
错误消息不太好,但预计程序无法工作,因为您在签名中包含
\nStr $output = $input.IO.extension("txt")\nRun Code Online (Sandbox Code Playgroud)\n但右侧返回一个IO::Path具有该扩展名的对象,但是$output类型为字符串。这是一个错误:
>>> my Str $s := "file.csv".IO.extension("txt")\nType check failed in binding; expected Str but got IO::Path (IO::Path.new("file.t...)\n in block <unit> at <unknown file> line 1\nRun Code Online (Sandbox Code Playgroud)\n>>> sub fun(Str $inp, Str $out = $inp.IO.extension("txt")) { }\n&fun\n\n>>> fun "file.csv"\nType check failed in binding to parameter \'$out\'; expected Str but got IO::Path (IO::Path.new("file.t...)\n in sub fun at <unknown file> line 1\n in block <unit> at <unknown file> line 1\nRun Code Online (Sandbox Code Playgroud)\n有时编译器会检测到不兼容的默认值:
\n>>> sub yes(Str $s = 3) { }\n===SORRY!=== Error while compiling:\nDefault value \'3\' will never bind to a parameter of type Str\n------> sub yes(Str $s = 3\xe2\x8f\x8f) { }\n expecting any of:\n constraint\nRun Code Online (Sandbox Code Playgroud)\n但你所拥有的远非字面意思,所以运行时检测。
\n要修复它,您可以
\n更改为Str() $output = $inp.IO.extension("txt")whereStr()表示“接受任何对象,然后将其转换为 Str”。所以$output最终会变成一个像这样的字符串"file.txt"MAIN 中可用的字符串。
Str $output = $inp.IO.extension("txt").Str但它是重复的Str.改成IO::Path() $output = $inp.IO.extension("txt")。类似地,这会转换为IO::Path对象收到的任何内容,因此,例如,您将"file.txt".IO在$output. 如果您这样做,您可能也想这样做$input以保持一致性。由于IO::Path对象是幂等的.IO(在eqv某种意义上),因此代码的其他部分不需要更改。
| 归档时间: |
|
| 查看次数: |
204 次 |
| 最近记录: |