第一章 初探 Perl6
Hello World - 标量变量
字符串(strings)能够被存储在所谓的标量变量(scalar variables)中,每个变量以$
符号开头,后面跟字母、数字、下划线或连字符。首次声明变量时以my
开头。
译注:
关于标量变量这个名词的解释有两种——
- 概念上指仅能存储一个值的变量(相对于数组等)。
- 标准变量、标准量,具有固定的类型与取值范围等,结构是固定的。
经过查证,普遍的解释更加偏向第一种,即“单个东西”。
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";
}