是否有一些模型可用于理解 Raku 中的容器、引用、原始、rw、\?

Posted

技术标签:

【中文标题】是否有一些模型可用于理解 Raku 中的容器、引用、原始、rw、\\?【英文标题】:Is there some model to use to understand containers, references, raw, rw, \ in Raku?是否有一些模型可用于理解 Raku 中的容器、引用、原始、rw、\? 【发布时间】:2020-11-14 03:18:52 【问题描述】:

在 perl5 中,您可以将 \ 视为一个指针,并通过以特定符号或 -> 为前缀来取消引用该指针。您还有使符号显式的类型团。在 perl5 中,底层 C 代码结构将提供一个与语言语法相关的良好模型。

在 Raku 中,您有一组概念,例如:容器(和非容器?)、绑定、=:= 的赋值、rawrw\ 等参数中的不同特征(这似乎与 perl5 的 \ 无关?)。

是否有一些基础模型我可以用来确定我在代码中的某个点实际使用了什么以及我有哪些选项?

【问题讨论】:

底层模型是什么意思?如果你说出你打算做什么,它可能会有所帮助。无论如何,一切都是元模型的基础。 即像“perl-gutsillustration”中那样的图形模型,或者如果元模型是定义容器的对象,则对“容器”是什么的描述的引用。我只在这里和那里找到碎片。元模型在哪里定义或 := 与 = 相比有何作用?它是否指定了 rw 特征? 【参考方案1】:

好的,我会试着给你一个心智模型:

    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;

通常,您不需要知道容器内是否有东西,因为大多数去容器化都是在幕后为您完成的。例如,如果您从子例程返回一个变量,它会自动从其容器中删除。除非子程序被标记为is raw

这对创建模型有帮助吗?

【讨论】:

嗨@elizabeth - 将其视为应用类型系统规则的容器是否公平? 我现在找到了这个:docs.raku.org/language/containers。可能是这样的:raku 中的“容器”是 Perl5 中所谓的“引用”(RV),其中一个容器指向一个实体。 “绑定”可能意味着设置容器指向的引用。 @psteve:是的,容器知道它接受哪些类型。 @KonradEisele - 我发现文档很简洁,但很精确。在我看来,raku 在处理这种家务方面领先 10 年,但不会打扰编码器(除非你愿意)。【参考方案2】:

我喜欢关于这个主题的出现日历文章 https://perl6advent.wordpress.com/2017/12/02/perl-6-sigils-variables-and-containers/ ,不确定这是否是你要找的,但它帮助我更好地了解正在发生的事情......

【讨论】:

我认为我需要阅读 VM 字节码以了解某些构造的任何其在 VM 中的实现以理解这些概念。 @KonradEisele 我不知道读取 VM 字节码会有多大帮助。 VM 并不真正了解 Raku。事实上,每次加载运行时都必须教授 Raku 对象模型的工作原理。【参考方案3】:

当你写这个时:

my $a = 'b';

$a = 'c';

say $a;

发生的事情有点像这样:

my $a := Scalar.new( value => 'b' );

$a.set-value('c');

say $a.get-value();

基本上创建了一个新的 Scalar 对象,$a 是一个指向它的指针。


当然它不是那么简单,因为你甚至不能在标量上调用 .new 并让它做任何事情。

Scalar 对象内部还存储了更多信息。 例如类型信息和任何默认值。

您对 $ 变量的真正想法都包含在 Scalar 对象中。

通常,此容器会尝试完全透明。 但是,您可以使用 .VAR 方法/宏获取标量对象。

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。

在下面,传递的 Scalar 内部的值被复制到一个不允许修改的新 Scalar。

sub bar ( $v )
  # $v = 3; # ERROR

bar $a

如果您将$v 声明为is rwis raw,则$v 实际上是指向您传入的标量容器的指针,就像上面的\v 一样。 (\vis raw 非常相似。)

【讨论】:

以上是关于是否有一些模型可用于理解 Raku 中的容器、引用、原始、rw、\?的主要内容,如果未能解决你的问题,请参考以下文章

如何理解Python中的容器对象

决策树模型(简单例子理解原理)

有没有办法(隐式)删除 Raku 角色混合?

深入理解 PHP7 中全新的 zval 容器和引用计数机制

彻底理解JVM常考题之分级引用模型

集合框架的一些理解