编程Perl 开发者

请讲述在 Perl 中数组、哈希和标量在不同类型字符串中的插值过程,以及与此机制相关的危险性。

用 Hintsage AI 助手通过面试

答案

在 Perl 中,双引号("")和某些模板(例如 heredoc)支持插值(变量替换)。标量的插值非常简单:

my $name = 'Bob'; print "Hello, $name! "; # Hello, Bob!

数组在双引号中插值后会变成字符串,其元素用 $" (默认是空格)分隔:

my @items = ('a','b','c'); print "List: @items "; # List: a b c

哈希以键=>值的字符串形式插值,元素用 $; 分隔:

my %h = (x => 1, y => 2); print "Hash: %h "; # Hash: x1y2 (可能会有所不同)

在单引号中(`' ')什么都不会插值——字符串将逐字输出。

还可以通过大括号来使用复杂的表达式进行插值:

print "${name}_test "; # Bob_test

危险性在于意外插值特殊字符,以及数组、哈希和标量行为的不同。


挖坑问题

为什么字符串 "Total: $total$val" 有时会错误工作?

常见回答:“一切都按原样替换!”

正确回答:

字符串 "Total: $total$val" 只能正确插值变量 $total,变量 $val 可能无法识别,或者 Perl 可能插值错误的范围,如果变量名相似的话。为了避免歧义,请使用大括号:

print "Total: ${total}${val} ";

历史


历史 1

在报告中,合计字符串看起来是这样的:"Итого: $sum руб."。在代码中添加了变量 $rub 后,字符串变成了 "Итого: $sum$rub",因此插值只对 $sum$ 生效,$rub 被跳过,出现了警告。没人明白,直到在输出中看到了空字符串。


历史 2

在形成 SQL 查询时,通过 @values 的数组插值没有使用 join:"IN (@values)"。这导致字符串用空格分隔,而不是预期的逗号列表。结果——SQL 错误和不正确的选择。


历史 3

为了输出哈希的键列表,在字符串中使用了 %h:"Keys: %h"。结果是键值对的串联字符串,而不是良好的键列表。应该使用:join ", ", keys %h