是否有一些模型可用于理解 Raku 中的容器、引用、原始、rw、\?
Is there some model to use to understand containers, references, raw, rw, \ in Raku?
在 perl5 中,您可以将 \
视为一个指针,并通过在特定印记或 ->
前加上前缀来取消对该指针的引用。您还拥有使符号显式化的 typeglobs。在 perl5 中,底层 C 代码结构 将提供一个与语言语法相关的良好模型。
在 Raku 中,您有一组概念,例如:容器(和非容器?)、绑定、使用 =
和 :=
赋值、raw
等参数中的不同特征和 rw
和 \
(这似乎与 perl5 的 \
无关?)。
是否有一些底层模型可以用来确定我在代码中的某个点实际使用的是什么以及我有哪些选项?
好的,我会尝试给你一个心智模型:
- Raku 中没有真正的赋值,只有绑定(像 NQP)
- Raku 中的一切 都是对象。
- 对象可以有属性,可以绑定到其他对象。
- Raku 添加语法糖来编写赋值,但实际上这只是将对象绑定到 Container 对象的属性。
那么这意味着什么:
# bind a container object to the name '$a' in the lexpad
my $a;
# bind an Int object to the value attribute of that container
$a = 42;
通常,您不需要知道容器内是否有东西,因为大多数去容器化都是在幕后为您完成的。例如,如果您 return 来自子例程的变量,它会自动从其容器中删除。除非子例程被标记为 is raw
.
这对创建模型有帮助吗?
我喜欢关于这个主题的降临节日历文章 https://perl6advent.wordpress.com/2017/12/02/perl-6-sigils-variables-and-containers/,不确定这是否是您要找的,但它帮助我 getter 更好地了解正在发生的事情.. .
当你这样写的时候:
my $a = 'b';
$a = 'c';
say $a;
发生的事情有点像这样:
my $a := Scalar.new( value => 'b' );
$a.set-value('c');
say $a.get-value();
基本上创建了一个新的 Scalar 对象,$a
是指向它的指针。
当然不是那么简单,因为您甚至不能在 Scalar 上调用 .new
并让它执行任何操作。
标量对象中还存储了更多信息。
例如类型信息和任何默认值。
真的如你所想 $
变量都包含在 Scalar 对象中。
通常此容器会尝试完全透明。
但是,您可以使用 .VAR
method/macro.
获取标量对象
my Int $a is default(42) = 3;
my $var = $a.VAR;
say $var.name; # $a
say $var.of; # (Int)
say $var.default; # 42
say $var.self; # 3
还有其他方法可以使这种透明度变得比透明更半透明。
sub foo ( \v ){ # the \ is so it isn't seen as a Type name
say v.VAR.name
v = 22;
}
foo $a; # $a
say $a; # 22
这是因为传递给子例程的是标量,而不是标量内部的值。
标量总是传递给函数调用,只是函数通常决定做一些事情,而不是允许您原始访问原始标量。
下面将传入的Scalar里面的值复制到新的不允许修改的Scalar中。
sub bar ( $v ){
# $v = 3; # ERROR
}
bar $a
如果您将 $v
声明为 is rw
或 is raw
,$v
实际上是指向您传入的标量容器的指针,就像 \v
多于。 (\v
与 is raw
非常相似。)
在 perl5 中,您可以将 \
视为一个指针,并通过在特定印记或 ->
前加上前缀来取消对该指针的引用。您还拥有使符号显式化的 typeglobs。在 perl5 中,底层 C 代码结构 将提供一个与语言语法相关的良好模型。
在 Raku 中,您有一组概念,例如:容器(和非容器?)、绑定、使用 =
和 :=
赋值、raw
等参数中的不同特征和 rw
和 \
(这似乎与 perl5 的 \
无关?)。
是否有一些底层模型可以用来确定我在代码中的某个点实际使用的是什么以及我有哪些选项?
好的,我会尝试给你一个心智模型:
- Raku 中没有真正的赋值,只有绑定(像 NQP)
- Raku 中的一切 都是对象。
- 对象可以有属性,可以绑定到其他对象。
- Raku 添加语法糖来编写赋值,但实际上这只是将对象绑定到 Container 对象的属性。
那么这意味着什么:
# bind a container object to the name '$a' in the lexpad
my $a;
# bind an Int object to the value attribute of that container
$a = 42;
通常,您不需要知道容器内是否有东西,因为大多数去容器化都是在幕后为您完成的。例如,如果您 return 来自子例程的变量,它会自动从其容器中删除。除非子例程被标记为 is raw
.
这对创建模型有帮助吗?
我喜欢关于这个主题的降临节日历文章 https://perl6advent.wordpress.com/2017/12/02/perl-6-sigils-variables-and-containers/,不确定这是否是您要找的,但它帮助我 getter 更好地了解正在发生的事情.. .
当你这样写的时候:
my $a = 'b';
$a = 'c';
say $a;
发生的事情有点像这样:
my $a := Scalar.new( value => 'b' );
$a.set-value('c');
say $a.get-value();
基本上创建了一个新的 Scalar 对象,$a
是指向它的指针。
当然不是那么简单,因为您甚至不能在 Scalar 上调用 .new
并让它执行任何操作。
标量对象中还存储了更多信息。 例如类型信息和任何默认值。
真的如你所想 $
变量都包含在 Scalar 对象中。
通常此容器会尝试完全透明。
但是,您可以使用 .VAR
method/macro.
my Int $a is default(42) = 3;
my $var = $a.VAR;
say $var.name; # $a
say $var.of; # (Int)
say $var.default; # 42
say $var.self; # 3
还有其他方法可以使这种透明度变得比透明更半透明。
sub foo ( \v ){ # the \ is so it isn't seen as a Type name
say v.VAR.name
v = 22;
}
foo $a; # $a
say $a; # 22
这是因为传递给子例程的是标量,而不是标量内部的值。 标量总是传递给函数调用,只是函数通常决定做一些事情,而不是允许您原始访问原始标量。
下面将传入的Scalar里面的值复制到新的不允许修改的Scalar中。
sub bar ( $v ){
# $v = 3; # ERROR
}
bar $a
如果您将 $v
声明为 is rw
或 is raw
,$v
实际上是指向您传入的标量容器的指针,就像 \v
多于。 (\v
与 is raw
非常相似。)