当前位置: 首页 > 文档资料 > Perl6 入门指导 >

第一章 初探 Perl6

优质
小牛编辑
121浏览
2023-12-01

Hello World - 标量变量

字符串(strings)能够被存储在所谓的标量变量(scalar variables)中,每个变量以$符号开头,后面跟字母、数字、下划线或连字符。首次声明变量时以my开头。

译注:
关于标量变量这个名词的解释有两种——

  1. 概念上指仅能存储一个值的变量(相对于数组等)。
  2. 标准变量、标准量,具有固定的类型与取值范围等,结构是固定的。

经过查证,普遍的解释更加偏向第一种,即“单个东西”。
A scalar is a single thing. —— Learning Perl, 7th Edition

my $this_is_a_variable;
my $ThisIsAnotherVariableButWeDontLikeItSoMuch;
my $this-is-a-variable;

变量名是大小写敏感的。

my $h;
my $H;

tutorial/scalars/hello_world_variable.p6

#!/usr/bin/env perl6
use v6;

my $greeting = "Hello World";
say $greeting;

my $Gábor-was-born-in = 'Hungary';
say $Gábor-was-born-in;

标量变量默认没有特定类型,后续我们将介绍如何限制变量使其只支持某种特定的类型,如数字、字符串等。

你也可以只声明一个变量而不去初始化它:

my $x;

在这种变量未定义的情况下它的值将是(Any)

译注:
my @array[3]; # [(Any) (Any) (Any)]
my $var; # (Any)
原文中说值是Any()应该不太准确。
Any类定义:Any is the class that serves as a default base class for new classes, and as the base class for most built-in classes. —— class Any

Hello World - 嵌入变量

在把一个标量变量放进常规的字符串中时,变量的值将会被直接嵌入进去。

tutorial/scalars/hello_world_variable_interpolation.p6

#!/usr/bin/env perl6
use v6;

my $name     = "Foo";
my $greeting = "Hello $name";
say $greeting;

将会打印出

Hello Foo

读取键盘输入

考虑这样一个情境:你需要询问用户的姓名。

当提示用户去回答一个问题的时候,最好使用prompt函数,简单来说就是在屏幕上打印一些文字但是句末不换行,以便等待用户输入。

在用户敲下回车后,程序会读入回车键之前的内容,即只读入一行。(Perl5程序员可以认为是使用了autochomp)

tutorial/scalars/read_stdin.p6

#!/usr/bin/env perl6
use v6;

my $name = prompt("Please type in yourname: ");

say "Hello $name";

数字运算符

可以对标量变量使用数字运算符(numerical operator)。

tutorial/scalars/numerical_operators.p6

#!/usr/bin/env perl6
use v6;

my $x = 3;
my $y = 11;

my $z = $x + $y;
say $z;            # 14

$z = $x * $y;
say $z;            # 33
say $y / $x;       # 3.66666666666667

$z = $y % $x;      # 模运算
say $z;            # 2

$z += 14;          # 等同于   $z = $z + 14;
say $z;            # 16

$z++;              # 等同于   $z = $z + 1;
$z--;              # 等同于   $z = $z - 1;

$z = 23 ** 2;      # 求幂运算
say $z;            # 529

将字符串自动转换为数字

在下面的情形中,我们能发现Perl6并不会介意你输入的是字符串,数字运算符+将会直接把输入的两个数相加。

tutorial/scalars/add.p6

#!/usr/bin/env perl6
use v6;

my $a = prompt "First number:";
my $b = prompt "Second number:";

my $c = $a + $b;

say "\nResult: $c";

字符串运算符

tutorial/scalars/string_operators.p6

#!/usr/bin/env perl6
use v6;

my $x = "Hello";
my $y = "World";

# ~ 是拼接运算符,将一个字符串附着在另一个字符串后面
my $z = $x ~ " " ~ $y;  # 等同于 "$x $y"
say $z;                 # Hello World

my $w = "Take " ~ (2 + 3);
say $w;                        # Take 5
say "Take 2 + 3";              # Take 2 + 3
say "Take {2 + 3}";            # Take 5

$z ~= "! ";             # 等同于 $z = $z ~ "! ";
say "'$z'";             # 'Hello World! '

~符号将两个字符串拼接在一起。

以上代码同时揭示了一点,任何运算都能都通过被大括号包裹的方式嵌入到字符串中。

字符串的拼接

tutorial/scalars/concat.p6

#!/usr/bin/env perl6
use v6;

my $a = prompt "First string:";
my $b = prompt "Second string:";

my $c = $a ~ $b;

say "\nResult: $c";

字符串的反复

tutorial/scalars/string_repetition.p6

#!/usr/bin/env perl6
use v6;

my $z = "Hello World! ";

# x 是用于重复字符串的运算符
my $q = $z x 3;
say "'$q'";         # 'Hello World! Hello World! Hello World! '

if语句 - 值的比较

if语句组合比较运算符(comparison operators)可以对值(values)或标量变量进行比较。

tutorial/scalars/if.p6

#!/usr/bin/env perl6
use v6;

my $age = 23;
if $age > 18 {
    say "You can vote in most countries.";
}

三元运算符

tutorial/scalars/ternary.p6

use v6;

my $age = 42;

if $age > 18 {
    say "Above 18";
} else {
    say "Below 18";
}

say $age > 18 ?? "Above 18" !! "Below 18";
[条件] ?? [为真时的值] !! [为假时的值]

比较运算符

关系运算符有两种:

  • 用于比较数值
  • 用于比较字符串(基于ASCII表)
</=
数值字符串(ASCII)意义
==eq等于
!=ne不等于
<lt小于
>gt大于
<=le小于等于
>=ge大于等于

详情参见 S03-operators.pod

3 == 4               # false
'35' eq 35.0         # false
'35' == 35.0         # true
13 > 2               # true
13 gt 2              # false !!!
"hello" == "world"   # throws exception
"hello" eq "world"   # false
"hello" == ""        # throws exception
"hello" eq ""        # false

tutorial/scalars/comparison_operators.p6

#!/usr/bin/env perl6
use v6;

say 4      == 4 ?? "TRUE" !! "FALSE";     # TRUE
say 3      == 4 ?? "TRUE" !! "FALSE";     # FALSE
say "3.0"  == 3 ?? "TRUE" !! "FALSE";     # TRUE
say "3.0"  eq 3 ?? "TRUE" !! "FALSE";     # FALSE
say 13     >  2 ?? "TRUE" !! "FALSE";     # TRUE
say 13     gt 2 ?? "TRUE" !! "FALSE";     # FALSE
#say "foo"  == "" ?? "TRUE" !! "FALSE";    # TRUE
say "foo"  eq "" ?? "TRUE" !! "FALSE";    # FALSE
#say "foo"  == "bar" ?? "TRUE" !! "FALSE"; # TRUE
say "foo"  eq "bar" ?? "TRUE" !! "FALSE"; # FALSE

译注:
如果取消注释上面代码中的那两行,将会提示错误:无法将字符串转换为十进制数,用于进行数值比较的字符串需要以合法数字或者小数点开头(Cannot convert string to number: base-10 number must begin with valid digits or '.')
由于这是错误而非警告,所以不会返回默认结果True,这是原文中的不准确之处。

布尔表达式(逻辑运算符)

运算符(符号形式)运算符(关键字形式)
&&and
||or
//orelse
^^xor
!not

译注:

  • or 不管左条件表达式是否成立,也要判断右边的表达式是否成立。
  • orelse 当左条件表达式成立时,不再判断右边的表达式是否成立。
if [条件1] and [条件2] {
}

if [条件1] or [条件2] {
}

if not [条件] {
}

tutorial/scalars/logical_operators.p6

#!/usr/bin/env perl6
use v6;

say (2 and 1);  # 1
say (1 and 2);  # 2
say (1 and 0);  # 0
say (0 and 1);  # 0
say (0 and 0);  # 0
say "---";

say (1 or 0);   # 1
say (1 or 2);   # 1
say (0 or 1);   # 1
say (0 or 0);   # 0
say "---";

say (1 // 0);     # 1
say (0 // 1);     # 0
say (0 // 0);     # 0
say "---";

say (1 xor 0);     # 1
say (0 xor 1);     # 1
say (0 xor 0);     # 0
say (1 xor 1);     # Nil
say "---";

say (not 1);       # False
say (not 0);       # True
say "---";

链式比较

tutorial/scalars/chained_comparison.p6

#!/usr/bin/env perl6
use v6;

my $a = prompt "Type in a number between 23 and 42: ";
if 23 <= $a and $a <= 42 {
    say "Good, $a is in the range.";
} else {
    say "Did I say between 23 and 42 ?";
}

# 也能够这样进行比较
if 23 <= $a <= 42 {
    say "Good, $a is in the range.";
} else {
    say "Did I say between 23 and 42 ?";
}

my $small = prompt "Type another number between 0 and $a: ";
my $big = prompt "Type another number between $a and 100: ";

if 0 <= $small <= $a <= $big <= 100 {
    say "good";
} else {
    say "something is fishy";
}

一个简易计算器 - 使用值的比较

tutorial/scalars/calculator.p6

#!/usr/bin/env perl6
use v6;

my $a        = prompt "Number:";
my $operator = prompt "Operator: [+-*/]:";
my $b        = prompt "Number:";

if $operator eq "+" {
    say $a + $b;
} elsif $operator eq "-" {
    say $a - $b;
} elsif $operator eq "*" {
    say $a * $b;
} elsif $operator eq "/" {
    say $a / $b;
} else {
    say "Invalid operator $operator";
}

一个简易计算器 - 使用given语句

使用given语句(相当于其他语言中的switch-case语句)能够让前文中的例子实现起来更加简洁。

Perl将会把本例中$operator的值与when关键字后的每一个值进行比较。当发现匹配时,程序将会执行相应匹配项后的代码块,并随后跳出given继续执行后续的代码。

如果未发现匹配项则会执行default(可选)后的代码块。

tutorial/scalars/calculator_given.p6

#!/usr/bin/env perl6
use v6;

my $a        = prompt "Number:";
my $operator = prompt "Operator: [+-*/]:";
my $b        = prompt "Number:";

given $operator {
    when "+" { say $a + $b; }
    when "-" { say $a - $b; }
    when "*" { say $a * $b; }
    when "/" { say $a / $b; }
    default  { say "Invalid operator $operator"; }
}

string类型方法:index

tutorial/scalars/string_functions_index.p6

#!/usr/bin/env perl6
use v6;

my $s = "The black cat jumped from the green tree";

say index $s, "e";                          # 2
say index $s, "e", 3;                       # 18

say rindex $s, "e";                         # 39
say rindex $s, "e", 38;                     # 38
say rindex $s, "e", 37;                     # 33

string类型方法:substr

tutorial/scalars/string_functions_substr.p6

#!/usr/bin/env perl6
use v6;

my $s = "The black cat climbed the green tree";
my $z;
$z = substr $s, 4, 5;                    # $z = black
say $z;
$z = substr $s, 4, *-11;                 # $z = black cat climbed the
say $z;
$z = substr $s, 14;                      # $z = climbed the green tree
say $z;
$z = substr $s, *-4;                     # $z = tree
say $z;
$z = substr $s, *-4, 2;                  # $z = tr
say $z;

"超级"or(条件联结)

tutorial/scalars/junctions.p6

#!/usr/bin/env perl6
use v6;

say "Please select an option:";
say "1) one";
say "2) two";
say "3) three";
my $c = prompt('');

if $c == 1 or $c == 2 or $c == 3 {
    say "correct choice: $c";
} else {
    say "Incorrect choice: $c";
}

if $c == 1|2|3 {
    say "correct choice: $c";
} else {
    say "Incorrect choice: $c";
}