Raku 编程/变量和数据
Raku 属于一类被称为动态语言的编程语言。动态语言使用数据类型可以在运行时改变的变量,并且不需要预先声明。动态语言的替代方案是静态语言,例如C或Java,在静态语言中,变量必须在使用前声明为特定的数据类型。
在像 C 这样的语言或它的衍生语言(例如C++,C#或Java)中,变量需要在使用前声明为一个类型。
unsigned short int x;
x = 10;
上面的代码并不完全准确,因为在 C 中你可以在声明变量时初始化它。
unsigned short int x = 10;
然而,变量 x
必须在声明之前不能使用。一旦它被声明为 unsigned short int
类型,你就不能使用 x
来存储其他类型的数据,比如浮点数或数据指针,至少在没有显式强制转换的情况下不能。
unsigned short int x;
x = 1.02; /* Wrong! */
unsigned short int y;
x = &y; /* Wrong! */
在像 Raku 这样的动态编程语言中,变量可以在首次使用时自动分配,而无需显式声明。此外,Raku 中的变量是多态的:它们可以是整数、字符串、浮点数或像数组或哈希表这样的复杂数据结构,而无需任何强制转换。以下是一些示例。
my $x;
$x = 5; # Integer
$x = "hello"; # String
$x = 3.1415; # Floating Point Number
上面的例子展示了一些我们在本书的其余部分会讨论的不同想法。一个重要的概念是注释。注释是源代码中的笔记,旨在供程序员阅读,并被 Raku 解释器忽略。在 Raku 中,大多数注释用 #
符号标记,并一直持续到行末。Raku 还具有嵌入式注释和多行文档,我们将在后面讨论这些内容。
我们对 Raku 数据并没有完全诚实。Raku 确实允许数据被赋予显式类型,如果你想要的话。默认情况下使用的是我们上面看到的这种多态数据,但你也可以声明一个标量只能保存整数、字符串、数字或其他完全不同的数据项。我们将在后面详细讨论 Raku 的显式类型系统。现在,更容易认为 Raku 中的数据没有显式类型(或者更具体地说,它不需要它们)。
我们上面看到的例子也展示了一个重要的关键字:my
。my
用于声明一个新的变量以供使用。我们将在后面详细讨论 my
及其用途。
正如我们在上面的简短示例中所看到的,Raku 变量前面带有符号,称为符号。符号在许多重要的用途中发挥作用,但其中最重要的是建立上下文。Raku 有四种类型的符号,用于建立不同类型的数据。我们上面看到的 $ 符号用于标量:单个数据值,如数字、字符串或对象引用。其他要使用的符号是 @,表示数据数组,% 表示数据哈希表,以及 & 表示子例程或可执行代码块。
- 标量
- 正如我们已经看到的那样,标量包含单个数据项,如数字或字符串。
- 数组
- 数组是相同类型数据的列表,按数字索引。
- 哈希表
- 哈希表是由字符串索引的、可能不同类型数据的集合。
- 代码引用
- 代码引用是指向可执行代码结构的指针,可以像数据一样传递并可以在代码中的不同位置调用。
我们上面已经看到了一些标量的用法,这里我们将展示一个稍微更全面的列表。
my $x;
$x = 42; # Decimal Integer
$x = 0xF6; # Hexadecimal Integer
$x = 0b1010010001; # Binary Integer
$x = 3.1415; # Floating Point Number
$x = 2.34E-5; # Scientific Notation
$x = "Hello "; # Double-Quoted String
$x = 'World!'; # Single-Quoted String
$x = q:to/EOS/; # Heredoc string
This is a heredoc string. It starts at the "q:to"
term and continues until we reach the terminator
specified in quotes above. This is useful for
large multi-line string literals. We will talk about
heredocs in more detail later
EOS
$x = MyObject.new(); # Object Reference
标量是 Raku 中最基本和最基本的数据类型,并且可能是你在程序中使用最频繁的类型。这是因为它们非常通用。
正如我们上面提到的,数组是数据对象的列表,被认为是相同类型。由于数组是标量的列表,因此数组中的一些元素可以是数字,而另一些可以是字符串,还有一些可以是其他数据。但是,这通常不被认为是数组的最佳用法。
数组以 @ 符号为前缀,可以使用方括号 [] 中的整数进行索引。以下是一些使用数组的示例。
my @a;
@a = 1, 2, 3;
@a = "first", "second", "third";
@a = 1.2, 3.14, 2.717;
一旦我们有了数组,就可以使用索引符号提取数组中的标量数据项。
my @a, $x;
@a = "first", "second", "third";
$x = @a[0]; # first
$x = @a[1]; # second
$x = @a[2]; # third
数组也可以是多维的。
my @a;
@a[0, 0] = 1;
@a[0, 1] = 2;
@a[1, 0] = 3;
@a[1, 1] = 4;
# @a is now:
# |1, 2|
# |3, 4|
数组也不必只存储标量,它们也可以存储任何其他数据项。
my @a, @b, @c, @d, %e, %f, %g, &h, &i, &j;
@a = @b, @c, @d;
@a = %e, %f, %g;
@a = &h, &i, &j;
这可以成为一些复杂数据结构的基础,我们将在后面详细讨论如何组合这样的结构。
哈希表在许多方面类似于数组:它们可以包含一组对象。但是,与数组不同的是,哈希表使用名称而不是数字来标识它们的项。以下是一些示例。
my %a = "first" => 1, "second" => 2, "third" => 3;
my $x = %a{"first"}; # 1
my $y = %a{"second"}; # 2
my $z = %a{"third"}; # 3
特殊的 =>
符号类似于逗号,只是它创建了一个对。对是字符串名称和关联数据对象的组合。哈希表有时可以被认为是成对的数组。还要注意,哈希表使用花括号 {} 来索引它们的数据,而不是像数组那样使用方括号 []。
哈希表还可以使用一种称为自动引用的特殊语法,以帮助简化哈希表值的查找。你可以在不使用花括号和引号 {" "}
的情况下,只使用尖括号 < >
来完成相同的工作。
my %a = "foo" => "first", "bar" => "second";
my $x = %a{"foo"}; # "first"
my $y = %a<bar> # "second"
哈希表中的对可以用另一种方法定义,而不使用 =>
运算符。对也可以使用副词语法定义。副词语法在整个 Raku 中使用,用于提供命名数据值,因此它不仅仅对哈希表有用。"name" => data
形式的对可以用副词语法写成 :name(data)
。
my %foo = "first" => 1, "second" => 2, "third" => 3;
my %bar = :first(1), :second(2), :third(3); # Same!
我们将在整个 Raku 中看到副词的许多用途,因此现在学习它们很重要。
Raku 使用特殊变量 $_
作为特殊的默认变量。$_
在没有提供其他变量时接收值,如果方法以点开头,则由方法使用。$_
可以通过名称显式使用或隐式使用。
$_ = "Hello ";
.print; # Call method 'print' on $_
$_.print; # Same
print $_; # Same, but written as a sub;
given "world!" { # Different way of saying $_ = "world"
.print; # Same as print $_;
}
默认变量在许多地方很有用,例如循环,它们可以用来清理代码并使操作更显式。我们将在学习过程中进一步讨论默认变量。