gpt4 book ai didi

where-clause - 无法在 CLASS 中使用带有 WHERE 子句的无符号变量?

转载 作者:行者123 更新时间:2023-12-04 11:09:49 25 4
gpt4 key购买 nike

模块一个 有一个成员变量名 c , 带有 WHERE 子句:

unit class A;

my \MAXVALUE = 1000_000;

has $.c where 0 < * < MAXVALUE;

method gist() {
"$!c";
}
套装 拉库利布 环境变量:
set RAKULIB="d:\scripts\Raku\A\lib"      # Windows
export RAKULIB="/opt/scripts/Raku/A/lib" # Linux
像这样使用模块A:
use A;

my $a = A.new(c => 1);
say $a;
但得到类型检查错误:
Type check failed in binding to parameter '<anon>'; expected Any but got Mu (Mu)
in whatevercode at D:\scripts\Raku\Raku\A\lib\.precomp\C6EB86CB837D3BCAAA3D85B66CE337C820700C08\6D\6DCD4CE23D88E2EE9568BA546C007C63D9131C1B line 1
in block <unit> at basic.rakutest line 3
这是一个错误吗?
乐库版本:
raku -v
This is Rakudo version 2020.05.1 built on MoarVM version 2020.05
implementing Raku 6.d.

最佳答案

打高尔夫球至: BEGIN say 1 < Mu显示基本相同的错误消息。
在您的代码中,MAXVALUE用值 Mu 初始化在编译时。您必须更改您的代码,以便评估 ... < MAXVALUE紧随其后 MAXVALUE已被初始化为除 Mu 以外的值.
在这个答案的其余部分:

  • 什么是最简单的编译时解决方案?
  • 如果您想使用运行时值怎么办?
  • 幕后发生了什么?
  • 错误消息是 LTA 吗?

  • 什么是最简单的编译时解决方案?
    您自己在此答案下方的评论中提供了一个很好的编译时解决方案,以回应我的第一个版本。
    也就是说,如果你希望保持符号纯粹是词法作用域,你应该从 my 开始。 :
    my constant MAXVALUE = 1000_000;
    问题解决了。
    如果您想使用运行时值怎么办? where 中的变量/符号/表达式如果子句在 WhateverCode expression 中,将在编译时评估它们。 .
    但如果您使用 lambda(使用 { ... } 语法),情况可能并非如此。如果您的代码中的行:
    has $.c where 0 < * < MAXVALUE;
    改为:
    has $.c where { 0 < $_ < MAXVALUE }
    那么你的代码就可以工作了。
    但是...
    如果您向 has 添加显式初始值线...
    has $.c where { 0 < $_ < MAXVALUE } = 10;
    ^^^^ Explicit initialization
    ...然后错误将返回,因为现在 where由于链式 react ,在编译期间调用子句:
  • 编译器决定检查初始化值是否通过 where查看。
  • 为此,编译器会评估 where编译时的子句;
  • 这反过来导致 MAXVALUE待评估——它包含 Mu在编译时,导致错误返回。

  • 幕后发生了什么?
    初始化 has 有编译期和运行期两个阶段。变量:
  • 在编译时,当一个类被组合时,实例将具有每个 has 的默认值。变量确定。三种常见的场景是:

    has陈述
    默认值

    has $foo;Anyhas $foo where some-condition;<anon>has $foo = 42;42
  • 在运行时,当一个类的实例被构建时,has 的值该特定实例的变量被设置,可能将它们初始化为类默认值以外的值。

  • 以下代码旨在演示该过程:
    BEGIN say 'code compile-time, start, outside class';
    say 'code run-time, start, outside class';

    sub init (*%_) { say "initializing {|%_}" }

    class foo {
    has $.bar;
    has $.baz where init(baz => $_);
    has $.buz where init(buz => $_) = 42;
    say 'run-time, at end of class';
    BEGIN say 'compile-time, at end of class';
    }
    BEGIN say 'compile-time, outside class again';

    say 'run-time, outside class again';
    say foo.new(buz => 99);
    显示:
    code compile-time, start, outside class
    compile-time, at end of class
    initializing buz 42
    compile-time, outside class again
    code run-time, start, outside class
    run-time, at end of class
    run-time, outside class again
    initializing buz 99
    foo.new(bar => Any, baz => <anon>, buz => 99)
    注意三个 has 的完成初始化完全构建的实例中的变量:
  • bar => Any .
    这是变量的通常默认初始化。
  • baz => <anon> .
    参见 say my Int $var;显示 (Int) ,因为有类型约束但没有显式初始化值的变量的默认值是类型约束对应的类型对​​象,而say my $var where 1;显示 (<anon>) ,反射(reflect)了 where 的匿名性质约束(与 subset 相比)。所以has $.baz where init(baz => $_);导致默认值 (<anon>) .
  • buz => 99 .
    这是唯一的has变量,其中一个 initializing ...显示了一行——而且,重要的是,有两行,而不是一行:
  • 第一行显示在 compile-time, at end of class 之后,即当编译器到达类声明的结束 curl 时。这是 Raku 做类(class)作文的时候,还有 buz获取默认值 42 .
  • 然后,在评估foo.new(buz => 99);期间,它在运行时构建类的实例,来自 initializing 99 .


  • 错误消息是 LTA 吗?
    在这个答案的第一个版本中,我写道:

    I'm not myself able to provide a coherent explanation ... whether it's considered a bug. I do currently consider the error message LTA.


    现在是我仔细讨论错误信息的时候了:
    Type check failed in binding to parameter '<anon>'; expected Any but got Mu (Mu)
    in whatevercode at ... A\lib ... line 1
    in block <unit> at ... line 3
  • Type check failed ...where检查失败。它被称为“类型检查”。鉴于 Raku 对“类型”这个词的正常使用,我认为这很好。
  • ... in binding to parameter '<anon>';我不确定“参数”指的是什么,也不确定 '<anon>' . imhh(在我的谦虚假设中)“参数”指的是 infix:«<» 的参数功能和 '<anon>'到存储在 $.c 中的值在匿名之前的编译时where在运行时尝试约束。
    陆路交通局? 也许类似 <where clause>而不是 <anon>将是可行的和适当的?
  • expected Any but got Mu (Mu)默认情况下,has变量期望 Mu ,不是 Any .所以这条消息似乎不是指$.c .所以,就像我对“参数”的假设一样,我认为这是关于 infix:«<» 的一个参数。功能。
    这是非常有用的信息。任何时候看到 but got Mu (Mu)您可以非常确定初始化某些值失败是问题的一部分,这里确实是这种情况。
  • in whatevercode爆炸发生在 WhateverCode ,所以这部分对于知道什么是 WhateverCode 的人很有用是。
    陆路交通局? 如果有人不知道什么是 WhateverCode是的,这部分很神秘。我想 in WhateverCode而不是 in whatevercode将是一个值得的改进。也许in WhateverCode (eg '* < 42') ,其中 '* < 42' 被固定为字面意思,而不是作为实际源代码,因为我认为这是不可行的,会更好吗?
  • at ... A\lib ...我省略的路径部分( ... )既有用(完整)又糟糕(非人类友好的长字符串)。
    陆路交通局? 也许将路径移动到最后会有所帮助:
    Type check failed ... got Mu (Mu)
    in whatevercode at A\lib line 1

    (Full path to A\lib: D:\scripts\Raku\Raku\A\lib\.precomp\
    C6EB86CB837D3BCAAA3D85B66CE337C820700C08\
    6D\6DCD4CE23D88E2EE9568BA546C007C63D9131C1B)
  • ... line 1“第 1 行”大概是指 whatevercode 中的第 1 行或 A\lib 中的第 1 行.无论哪种方式,它都不是特别有用。
    陆路交通局? 也许更清楚地说明第 1 行所指的是什么是可行和适当的,如果它指的是 A\lib ,然后使其准确指向 whatevercode .
  • in block <unit> at line 3这很有用。
  • 关于where-clause - 无法在 CLASS 中使用带有 WHERE 子句的无符号变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66437935/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com