当遇到参考模式时,符合人体工程学会有什么?

发布于 01-22 15:08 字数 2684 浏览 1 评论 0 原文

我读过 rfc 2005 是重复的操作。我说遇到参考模式,我不是在谈论在第一次迭代中遇到参考模式,例如以下一个:

let x = &String;
// The binding mode is `move`, so x is of type `&String`

但是在某些情况下, banding模式转移到> ref/ref/ref mut 在上一个非参考模式迭代期间,然后遇到参考模式

我已经非常仔细地阅读了RFC,并且发现此句子 *默认绑定模式 *仅在与非参考模式匹配的引用时更改。,这是指 code>参考模式将对匹配过程无能为力,但是有人告诉我参考模式会将绑定模式重置回默认移动(请参阅情况2)。

在两种情况下,“正确”的推论似乎相互冲突:

正确意味着推断的类型与编译器推断的类型相同,但是我不知道推断过程是否也正确,这就是我发布此问题的原因。

// case 1
let (a, b) = &(&String, &String); // a and b are of type &&String
// case 2
let (&a, &b) = &(&String, &String); // a and b are of type String

案例1的推断:

首先,我们匹配&(& string,& string)反对(a,b)(a,b) )非参考模式,因此我们Deref &(& string,string) and set bind> band> binding模式 移动(默认一个) ref 。然后,我们将(& string,string)与(a,b) ref binding模式, a匹配 b 是类型&& string

为什么它停止在匹配(& string,& string)(a,b) ,我们不应该继续匹配&amp ; string 针对 a b 分别?

如果我们继续,请匹配& string a , a 是 is 参考模式,我们应该什么现在?

案例2的推断:

首先,我们匹配&amp;(&amp; string,&amp; string)反对(&amp; a ,,&&amp; b))( &amp; a,&amp; b)非参考模式,所以我们deref &amp;(&amp; string,&amp; string) and set 绑定模式 <代码> ref 。然后,我们匹配(&amp; string,&amp; string)(&amp; a,&amp; b),基本上是匹配&amp; string 反对&amp; a &amp; a is 参考模式,因此我们重置绑定模式回到移动 ,制作类型字符串的。

矛盾:

在情况2中,当遇到参考模式时,我们要做的是将绑定模式重置为默认的移动。但是,在情况1(如果我们那时我们不停下来,请保持匹配 string 针对 a ), a 也是参考模式,如果我们仍然重置绑定模式移动,则A将具有类型&amp; string 而不是&amp;&amp;&amp; string

还有另一个问题,哪个是何时推断算法stop ?在情况1中,如果算法应该在此时停止,那么一切都会使人感官。

I have read the rfc 2005, knowing the process of manipulation is a repeated operation. And I say encounters reference pattern, I am not talking about encountering reference pattern at the first iteration like the following one:

let x = &String;
// The binding mode is `move`, so x is of type `&String`

But some cases where binding mode is shifted to ref/ref mut during the previous non-reference pattern iteration, and then encounters a reference pattern.

I have read the rfc very carefully, and I found this sentence The *default binding mode* only changes when matching a reference with a non-reference pattern., does this mean reference pattern will do nothing to the matching process, but someone told me reference pattern will reset the binding mode back to the default move(see case 2).

There are two cases where the "correct" inferences seem conflict with each other:

Correct means that the inferred type is the same as the one inferred by the compiler, but I don't know if the inferring process is also correct, which is the reason why I post this question.

// case 1
let (a, b) = &(&String, &String); // a and b are of type &&String
// case 2
let (&a, &b) = &(&String, &String); // a and b are of type String

Inference for case 1:

First, we are matching &(&String, &String) against (a, b), and (a, b) is non-reference pattern, so we deref &(&String, &String) and set binding mode from move(default one) to ref. Then we are matching (&String, &String) against (a, b) , with ref binding mode, a and b are of type &&String.

Why did it stop at matching (&String, &String) against (a, b), shouldn't we continue to match &String against a and b respectively?

If we continue, matching &String against a, a is reference pattern, what should we do now?

Inference for case 2:

First, we are matching &(&String, &String) against (&a, &b), (&a, &b) is non-reference pattern, so we deref &(&String, &String) and set binding mode to ref. Then we match (&String, &String) against (&a, &b), which is basically matching &String against &a, &a is reference pattern, so we reset binding mode back to move, making a of type String.

Contradiction:

In case 2, when encounters reference pattern, what we do is to reset binding mode to the default move. However in case 1(if we didn't stop at that point, keeping matching &String against a), a is also reference pattern, if we still reset binding mode to move, then a will have type &String instead of &&String.

And there is another question, which is when should this inferring algorithm stop? In case 1, if the algorithm should stop at that point, then everything makes senses.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故事还在继续 2025-01-29 15:08:54

似乎我找到了答案。有几件事要澄清:

  1. 匹配人体工程学仅涵盖了我们与非参考模式匹配的情况参考,所以这个问题的标题是错误的,匹配人体工程学当相遇参考模式时,无能为力。 的算法匹配人体工程学只是:

      fn match_ergonomics(){
        if(我们匹配的参考为`&amp; xx`){
            binding_mode =`ref`
        } else if(我们匹配的参考为`&amp; mut xx`){
            if(binding_mode ==`ref`){
                binding_mode =`ref`;
            } 别的 {
                binding_mode =`ref mut`;
            }
        }
    }
     
  2. 默认绑定模式匹配符合符合人体工程学的概念,但这不是独家对于匹配符合人体工程学的情况,它已集成到整个生锈匹配系统中。

  3. 参考模式的概念可能会令人困惑。在 rfc 中:

    参考模式是任何可以匹配参考而无需强制的模式。参考模式包括绑定,通配符( _ ), const 参考类型,以及以&amp; &amp; mut开头的模式。

    在Rust Reference中,它只是模式以&amp;/&amp; mut

    开始

  4. 匹配是一个递归过程,对于本递归中的每个过程,有几种情况,取决于模式我们正在遇到,其中包括匹配人体工程学案例。

  5. 实际上在两种情况下,我们将更改DBD,一个是与非参考模式参考匹配,而另一个则是匹配的&amp; [ MUT] PAT 针对参考

    匹配 更改为dbm
    non-ref模式 参考 设置为 ref ref mut
    &amp; [mut] pat 参考 设置为移动

匹配算法

// The terminologies we are using in this algorithm come from rust reference
If no `default binding mode` is set, set the `default binding mode` to `move`.

If the pattern is an identifier pattern:
    If we have explicit `ref`:
        bind by reference;
    else if we have explicit `ref mut`:
        bind by mutable reference;
    else:
        // When explicit `ref/ref mut` are absent
        // default binding mode decides how to bind
        If the binding mode is `move`, bind directly.
        If the binding mode is `ref`, bind by immutable reference.
        If the binding mode is `ret mut`, bind by mutable reference.
    
    If the pattern has an inner pattern, repeat this process with that pattern.

else if the pattern is a `&[mut]` reference pattern:
    // matching `&[mut]` against non-reference triggers
    // a compiler error
    Ensure that we are matching against a `&[mut]` reference.

    Dereference the scrutinee expression.
    Set the binding mode to `move`.  
    Repeat this process with the inner pattern.

else if the pattern is any kind of destructuring pattern:
    Set `T` to the type implied by the pattern.
    Ensure that we are matching against a `T` value or `&[mut] T` reference.
    
    // cases covered by match ergonomics
    If we are matching against a `&T` reference:
        Dereference the scrutinee expression.
        Set the binding mode to `ref`.
    else if we are matching against a `&mut T` reference:
        Dereference the scrutinee expression.
        If the binding mode is `move`, set the binding mode to `ref mut`.


    else
        destructure the value;
    Repeat this process for all fields in the pattern.

>对于案例1和2

// case 1
let (a, b) = &(&String, &String); // a and b are of type &&String

第一个过程:我们正在匹配(a,b)&amp;(&amp; string,string)匹配,该 都进入案例3(任何另一种破坏性模式)。 &amp;(&amp; string,&amp; string)&amp; t ,因此请deref itf it and 默认绑定模式 to 参考

第二个过程:我们与(a,b)匹配(&amp; string,string,string),这是基本上与 a 相匹配的代码>&amp; string 。 a 是标识符模式,它进入案例1。我们没有明确的 ref/ref/ref mut 默认绑定模式 is ref ,因此,通过不变的参考,制作 a 的类型&amp; amp; string

所有模式都是匹配的,递归结束了。

// case 2
let (&a, &b) = &(&String, &String); // a and b are of type String

第一个过程:我们匹配(&amp; a,&amp; b) fite &amp;(&amp; string,&amp; string),该进入案例3。derefand deref and and SET 默认绑定模式 to ref

第二个过程:我们匹配(&amp; a,&amp; b) fiter (&amp; string) ,&amp; string),基本上与&amp; a &amp; string 匹配。 &amp; string 参考模式,因此我们进入了案例2,并设置默认绑定模式 移动&amp; a =&amp; string ,因此A具有类型 String

所有模式都匹配,递归结束了。

该算法可能不是那么准确,欢迎那些知道这些东西编辑此答案的人。

Seems that I have found the answer. There are several things to clarify:

  1. match ergonomics only covers the cases where we are matching non-reference pattern against reference, so the title of this question is wrong, match ergonomics does nothing when encounters reference pattern. The algorithm of match ergonomics is just something like:

    fn match_ergonomics() {
        if (the reference we are matching is `&xx`) {
            binding_mode = `ref`
        } else if (the reference we are matching is `&mut xx`) {
            if (binding_mode == `ref`) {
                binding_mode = `ref`;
            } else {
                binding_mode = `ref mut`;
            }
        }
    }
    
  2. default binding mode is a concept introduced for match ergonomics, but this is not exclusive to the cases covered by match ergonomics, it has been integrated into the whole rust matching system.

  3. The concept of reference pattern can be confusing. In rfc:

    A reference pattern is any pattern which can match a reference without coercion. Reference patterns include bindings, wildcards (_), consts of reference types, and patterns beginning with & or &mut.

    While in rust reference, it is just pattern beginning with &/&mut.

  4. Matching is a recursive process, for every procedure in this recursion, there are several cases depending what pattern we are encountering, which include the match ergonomics cases.

  5. There are actually two situations where we will change the DBD, one is matching non-reference pattern against reference, and the other is matching &[mut] pat against reference.

    matching against change to DBM
    non-ref pattern reference set to ref or ref mut
    &[mut] pat reference set to move

Matching algorithm

// The terminologies we are using in this algorithm come from rust reference
If no `default binding mode` is set, set the `default binding mode` to `move`.

If the pattern is an identifier pattern:
    If we have explicit `ref`:
        bind by reference;
    else if we have explicit `ref mut`:
        bind by mutable reference;
    else:
        // When explicit `ref/ref mut` are absent
        // default binding mode decides how to bind
        If the binding mode is `move`, bind directly.
        If the binding mode is `ref`, bind by immutable reference.
        If the binding mode is `ret mut`, bind by mutable reference.
    
    If the pattern has an inner pattern, repeat this process with that pattern.

else if the pattern is a `&[mut]` reference pattern:
    // matching `&[mut]` against non-reference triggers
    // a compiler error
    Ensure that we are matching against a `&[mut]` reference.

    Dereference the scrutinee expression.
    Set the binding mode to `move`.  
    Repeat this process with the inner pattern.

else if the pattern is any kind of destructuring pattern:
    Set `T` to the type implied by the pattern.
    Ensure that we are matching against a `T` value or `&[mut] T` reference.
    
    // cases covered by match ergonomics
    If we are matching against a `&T` reference:
        Dereference the scrutinee expression.
        Set the binding mode to `ref`.
    else if we are matching against a `&mut T` reference:
        Dereference the scrutinee expression.
        If the binding mode is `move`, set the binding mode to `ref mut`.


    else
        destructure the value;
    Repeat this process for all fields in the pattern.

Inference for case 1 and 2

// case 1
let (a, b) = &(&String, &String); // a and b are of type &&String

First procedure: we are matching (a, b) against &(&String, &String), which goes into case 3(any other kind of destructuring pattern). &(&String, &String) is a &T, so deref it and set default binding mode to ref.

Second procedure: we are matching (a, b) against (&String, &String), which is basicially matching a against &String. a is a identifier pattern, which goes into case 1. We don't have explicit ref/ref mut and default binding mode is ref, so bind by immutable ref, making a of type &&String.

All the patterns are matched, recursion is over.

// case 2
let (&a, &b) = &(&String, &String); // a and b are of type String

First procedure: we are matching (&a, &b) against &(&String, &String), which goes into case 3. Deref and set default binding mode to ref

Second procedure: we are matching (&a, &b) against (&String, &String), which is basically matching &a against &String. &String is a reference pattern, so we goes into case 2, and set default binding mode to move, &a = &String, so a has type String

All the patterns are matched, recursion is over.

The algorithm may not be that accurate, welcome people who know this stuff to edit this answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文