Something about Perl (2) 函数 哈希表

    技术2022-05-11  114

    函数:

    sub关键字用于定义函数sub function_name{    do_something;}

    调用函使用符号&    ampersand&function_name;

    函数的返回值初步通常返回代码块中最后执行语句的值。例如:sub list_from_fred_to_barney {  if ($fred < $barney) {    # Count upwards from $fred to $barney    $fred..$barney;  } else {    # Count downwards from $fred to $barney    reverse $barney..$fred;  }}$fred = 11;$barney = 6;@c = &list_from_fred_to_barney; # @c gets (11, 10, 9, 8, 7, 6)如果最后一行是print一类语句,返回值为1,表示调用成功,返回false表示失败。还有更多复杂的情况。

    函数参数在函数中, @_为参数数组列表,或使用$_[index]访问任意一个参数。 在Perl中函数可能修改参数的值,例如:$A = 1;$B = 2;sub switch{($_[0],$_[1])=($_[1],$_[0]);}print $A."/n".$B."/n";&switch($A,$B);print "After switch/n";print $A."/n".$B."/n";输出:1       2After switch2       1

    定义私有变量Lexical Variables:关键字mycreate private variables called lexical variables at any time with the my operatorsub max {  my($a, $b)=@_;    # give names to the parameters  if ($a > $b) { $a } else { $b }}被关键字my修饰的变量仅在代码块中有效.

    local关键字,在函数中用local修饰的全局变量,local变量在函数代码块中的值在调用其他函数时有效,但离开这个函数代码块后就不再有效。例子:$office = "global";      # Global $officesub say { print "$office/n"; }          # print the currently visible $officesub fred { local($office) = "fred"; &say( ); }sub barney { my($office) = "barney"; print $office."/n";&say( ); }&say( );                           # says "global", accessing $office directly&fred( );                                # says "fred", dynamic scope,   # because fred's local $office hides the global&barney( );                              # says "global", lexical scope;输出:      # barney's $office is visible only in that blockglobal   显示全局变量的值fred   全局变量在fred中被修改并显示,但退出函数fred后全局变量office会恢复原有的值barney   局部变量office的值是barneyglobal    在say函数中可见的只有全局变量office

    变长参数名,支持变长参数的最大值函数:$maximum = &max(3, 5, 10, 4, 6);sub max {  my($max_so_far) = shift @_;  # 取出队首元素作为第一个极大值  foreach (@_) {               # 处理剩余的元素    if ($_ > $max_so_far) {    # 是否更大?      $max_so_far = $_;    }  }  $max_so_far;}

    use strict; 选项在perl中对于变量的使用非常随意,因此变量名输入错误可能带来严重后果(输入错误的变量名会被误认为新变量)当使用use strict;后源代码中所有的新变量声明都必须以my关键字开头,不使用my关键字而使用新变量名会造成一个编译错误.编写perl程序时强烈建议使用这个选项.

    return 操作符,从函数中返回值或表达式当表达式或值本身就是函数最后执行的语句时,return操作符不是必须的.

    &操作符在不引起函数调用歧义的情况下也不是必须的,只要系统中没有定义相同名称的函数即可.

    Perl数组大小过大的性能隐患:sub total{    my $total = pop @_;    foreach (@_){    $total+=$_;    }    $total;}print total(1..1e7);这个简单的累加函数会导致Perl解释器占用300MB以上的内存,系统反应类似死机,使用大数组要谨慎.

     

    Hash 哈希一个哈希表是由keys和values组成的数据对集合.其中keys和values都是任意标量, keys总是字符串,如果使用数学表达式作为key,它将会被计算出来并存储为字符串.例如如果key是50/20,那么会被保存为字符串"2.5"keys在一个hash结构中是唯一的.

    访问hash表中的value$hash{$some_key}  curly braces

    对于哈希键与值的关系可以通过以下方法理解"the family_name of fred is flintstone". So the hash is named family_name. Then it becomes clear what the relationship is between the keys and their values. hashtable of Key is Value.

    作为整体的hash表使用% percent sign 访问.hash表可以和键-值对的数组相互转换%some_hash = ("foo", 35, "bar", 12.4, 2.5, "hello",      "wilma", 1.72e30, "betty", "bye/n");@any_array = %some_hash;在这种过程中,键和值的顺序是任意的.

    可以通过%new_hash = %old_hash; 拷贝hash表

    常用用法%inverse_hash = reverse %any_hash;逆序一个hash表的意义,是将键-值对 变成了值-键对,这是一种非常常用的用法%inverse_hash 中的键是%any_hash中的值如果%any_hash中的值不唯一,%inverse_hash中该键的值可能对应在%any_hash中的任何一个匹配的键.(而不会警告或出错)

    使用=>匹配键值对,简单地替换comma , 即可%last_name = (  "fred" => "flintstone",  "betty" => "rubble",);

    keys/values 函数用于对%hash进行操作的函数keys 返回包含所有key的数组,values 返回包含所有value的数组注意在标量上下文中,返回的实际上是key的总数,例如:my $count = keys %hash;  # gets a number of key-value pairs

    当把%hash当作布尔值使用,例如:if(%hash)当%hash至少含有一个键-值对时,结果为真.

    each 函数, 返回一个键-值对,通常用法:while ( ($key, $value) = each %hash ) {  print "$key => $value/n";}当each遍历完所有元素会返回一个空数组,此时跳出循环.可以将each看作一个简单的迭代器.有很多情况会导致each迭代器被重置,例如使用了keys或values函数,在each遍历中增加键-值对不一定会重置each,最好不要这样做!!!仅仅使用each作为遍历(只读)的工具.对于嵌套的迭代器each,每个%hash有其自己的迭代元,不会混淆.

    exists 函数检验一个给定的key是否存在于hash表中if (exists $books{"dino"}) {  print "Hey, there's a library card for dino!/n";}

    <STDIN>在foreach和while循环中的不同在while循环中使用默认变量$_while (<STDIN>) {    print "I saw $_";}打印每条输入(包含换行符)

    使用foreach循环完成同样的工作foreach (<STDIN>) {    print "I saw $_";}这里有着细微的不同,在while循环中,每次读取<STDIN>的一行,然后进入循环处理.而foreach循环中,<STDIN>被用在一个数组语境中,因此在运行循环体之前,必须读取完<STDIN>所有的内容,在处理大文件和大输入的时候,使用while能取得更好的效能(一次处理一行),因此,只要可能,就使用while,而非foreach

    Diamond operater <>对于大量Unix工具,cat或sed 使用连字符hyphen - 代表标准输入例如:  fred- betty表示:文件fred 标准输入 文件bettywhile (<>) {  chomp;  print "It was $_ that I saw!/n";}读取参数作为输入并打印注意<>用于处理输入,而输入的每一行被依次放入了$_变量

    标准输出 printprint @array; #依次打印数组中元素,不留空格print "@array"; #依次打印数组中元素,元素之间有空格如果@array的元素是以换行结尾的字符串,在双引号内的@array打印时还是会加上空格,看起来第一行之后的行有一个空格的缩进.最好用chomp处理一下print后面的参数是数组语境,使用<>用于数组语境时,得到的是一个由每行字符串组成的数组,因此可以这样使用print <>; #与cat命令使用方式相同print sort <>; #与sort命令使用方式相同

    @ARGV 参数字符串在程序开始之前,@ARGV数组被初始化为由参数填充的数组<>在@ARGV中查找需要的参数,因此可以人为初始化@ARGV数组@ARGV = qw# larry moe curly #;  #读取这三个文件,无论调用参数为何while (<>) {  chomp;  print "It was $_ that I saw in some stooge-like file!/n";} 


    最新回复(0)