【问题标题】:How can I skip elements in Perl list assignment akin to Haskell pattern matching?如何跳过类似于 Haskell 模式匹配的 Perl 列表分配中的元素?
【发布时间】:2015-03-15 17:51:26
【问题描述】:

在 Haskell(和其他各种函数式编程语言)中,pattern matching 可用于分配列表的特定元素,同时丢弃其他元素:

Prelude> let [x, _, z] = "abc"
Prelude> x
'a'
Prelude> [z, x]
"ca"

请注意,“_”不是变量,也没有被赋值:

Prelude> _

<interactive>:5:1: Pattern syntax in expression context: _

对于用 Perl 编写的 Irssi 脚本,我想做类似的事情并丢弃 '@_' 的第二个nd 元素(即不将其分配给任何东西):

my ($message, _, $windowItem) = @_;

此操作失败并显示错误消息:“Can't declare constant item in "my" at [...]overlength_filter.pl line 17, near ") ="

那么这个下划线通配符的 Perl 等价物是什么?

【问题讨论】:

  • 在不遇到正则表达式的情况下很难找到答案。 :-/

标签: perl pattern-matching variable-assignment


【解决方案1】:

只需将其分配给undef

my ($message, undef, $windowItem) = @_;

【讨论】:

  • 完美,谢谢! :-) 对于它的价值,这里是完成的代码:lpaste.net/118597
【解决方案2】:

你也可以取数组的一部分:)

my( $message , $winItem ) = @_[ 0, 2];

【讨论】:

  • 如果我想要第一个、第三个和第五个元素会发生什么?使用undef 很明显。对于切片,我会使用@_[0, 2, 4] 吗?无论如何,读过this question,看来这种切片方法效率较低,所以我认为undef 模式通常是更好的做法。
  • @JamesHaigh:我认为您误解了您链接到的问题,无论如何,在您编写一个 clear 的程序之前,您不应该考虑速度和效率和可维护的 尽可能。我个人认为数组切片符号通常更清晰,例如,my ($x, $y) = @array[4,9]my (undef, undef, undef, undef, $x, undef, undef, undef, undef, $y) = @array
  • Borodin:当然,对于像您描述的示例这样的情况,它肯定更紧凑,特别是因为 'undef' 是 5 个字符而不是 1 个字符,但如果您的主要目标是 代码可读性 和 maintainability,那么这种带有长参数数组的编程模式可能无论如何都不是最佳实践。此外,您可能最好先使用更适合编写优雅、可读、可维护的代码的语言。我可能偏向于纯函数式编程语言,但即使在命令式范式中,Python 也是代码可读性的不错选择。
  • @Borodin:我不同意你直到最后才任何考虑速度和效率。我不是在这里谈论过早的优化。我认为养成使用编程模式的习惯 很重要,这样可以直接避免效率低下,尽管对于这么小的列表来说这并不重要。在最坏的情况下,如果您在编写程序时没有任何注意效率,那么您最终可能会遇到设计上存在缺陷的资源消耗,实际上需要从头开始重新实现修复。
  • @Borodin:我从this DDG search 的 Q/A 信息框中发现了这个问题,同时试图理解 Perl 切片符号的格式(顺便说一句,这个答案可以参考 Perl 的有关切片的文档),并且只是略过它。我解释了“没有创建一个全新的数组”和“没有 Perl 在后台复制加载的数据”来表明当 Perl 计算 @array[@slice] 时,它实际上会生成一个分配给模式匹配的 LHS 列表之前的新数组,undef 方法可以避免这种情况。不是这样吗?
猜你喜欢
  • 2021-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
  • 2015-05-30
  • 1970-01-01
相关资源
最近更新 更多