当特征和结构使用相同的方法名称时如何调用方法? [英] How to call a method when a trait and struct use the same method name?

查看:38
本文介绍了当特征和结构使用相同的方法名称时如何调用方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个程序因为无限递归而死了:

使用 std::any::Any;特征 Foo {fn get(&self, index: usize) ->选项<&Any>;}impl Foo for Vec<i32>{fn get(&self, index: usize) ->选项<&Any>{Vec::get(self, index).map(|v| v as &Any)}}fn 主(){让 v:Vec i32= vec![1, 2, 4];println!("结果:{:?}", v.get(0))}

编译器本身对此发出警告:

警告:函数不能不重复就返回-->src/main.rs:8:5|8 |fn get(&self, index: usize) ->选项<&Any>{|_____^ 从这里开始...9 ||Vec::get(self, index).map(|v| v as &Any)10 ||}||_____^ ...到此结束|= 注意:#[warn(unconditional_recursion)] 默认开启注意:递归调用站点-->src/main.rs:9:9|9 |Vec::get(self, index).map(|v| v as &Any)|^^^^^^^^^^^^^^^^^^^^^= 帮助:如果这是故意的,`loop` 可以更好地表达意图

为什么通用调用语法在这种情况下不起作用?编译器不明白我想调用 Vec::get 而不是 Foo::get.

如果我不想更改函数名称,我该如何解决这个问题?

解决方案

要指定调用哪个方法,无论是固有的还是从特性提供的,您需要使用 完全限定语法:

Type::function(maybe_self, needed_arguments, more_arguments)Trait::function(maybe_self, needed_arguments, more_arguments)

您的案例不起作用,因为 Vec 没有名为 get 的方法!get 来自 Deref 实现到 [T].

最简单的解决方法是直接调用 as_slice:

self.as_slice().get(index).map(|v| v as &Any)

您也可以使用在这种情况下需要尖括号的完全限定语法 (<...>) 以避免声明数组文字时产生歧义:

<[i32]>::get(self, index).map(|v| v as &Any)

<小时><块引用>

通用调用语法

请注意,虽然 Rust 最初使用术语通用函数调用语法(UFCS),但该术语的用法与现有理解的编程术语相冲突,因此不建议使用它.替换术语是完全限定的语法.

This program dies because of infinite recursion:

use std::any::Any;

trait Foo {
    fn get(&self, index: usize) -> Option<&Any>;
}

impl Foo for Vec<i32> {
    fn get(&self, index: usize) -> Option<&Any> {
        Vec::get(self, index).map(|v| v as &Any)
    }
}

fn main() {
    let v: Vec<i32> = vec![1, 2, 4];
    println!("Results: {:?}", v.get(0))
}

The compiler itself warns about this:

warning: function cannot return without recurring
  --> src/main.rs:8:5
   |
8  |       fn get(&self, index: usize) -> Option<&Any> {
   |  _____^ starting here...
9  | |         Vec::get(self, index).map(|v| v as &Any)
10 | |     }
   | |_____^ ...ending here
   |
   = note: #[warn(unconditional_recursion)] on by default
note: recursive call site
  --> src/main.rs:9:9
   |
9  |         Vec::get(self, index).map(|v| v as &Any)
   |         ^^^^^^^^^^^^^^^^^^^^^
   = help: a `loop` may express intention better if this is on purpose

Why does universal call syntax not work in this case? The compiler does not understand that I want to call Vec::get not Foo::get.

How can I fix this, if I do not want to change function names?

解决方案

To specify which method to call, whether inherent or provided from a trait, you want to use the fully qualified syntax:

Type::function(maybe_self, needed_arguments, more_arguments)
Trait::function(maybe_self, needed_arguments, more_arguments)

Your case doesn't work because Vec doesn't have a method called get! get is provided from the Deref implementation to [T].

The easiest fix is to call as_slice directly:

self.as_slice().get(index).map(|v| v as &Any)

You could also use the fully qualified syntax which requires the angle brackets in this case (<...>) to avoid ambiguity with declaring an array literal:

<[i32]>::get(self, index).map(|v| v as &Any)


universal call syntax

Note that while Rust originally used the term universal function call syntax (UFCS), the usage of this term conflicted with the existing understood programming term, so the use of it is not suggested. The replacement term is fully qualified syntax.

这篇关于当特征和结构使用相同的方法名称时如何调用方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆