gpt4 book ai didi

generics - 为什么在通用使用时调用特征方法不会调用同名的固有方法?

转载 作者:行者123 更新时间:2023-12-02 18:03:18 26 4
gpt4 key购买 nike

我是 Rust 新手,我在通用函数中有一个奇怪的行为以及一些关于它的问题。我明白结果,但不知道是否正常:

trait A {
fn a() {
println!("Oh Noooo...");
}
fn b();
}

struct SA {}

impl SA {
fn a() {
println!("sa");
}

fn b() {
println!("b");
}
}

impl A for SA {
fn b() {
println!("b2");
}
}

fn foo<T>() where T: A {
T::a();
// <T as T>::a(); // -> Generate an error a not in T
}

fn bar<T>() where T: A {
T::b();
// <T as T>::b(); // -> Generate an error b not in T
}

fn main() {
//<SA as SA>::a(); // -> Generate an error not found in SA
SA::a();
foo::<SA>();
SA::b();
bar::<SA>();
}
sa
Oh Noooo...
b
b2

Link to the playground

我的问题是关于“Oh Noooo...”。我知道代码不是常规函数a()不在 impl A for SA 中但为什么在通用函数中, is 不是 a()SA这就是所谓的?我以为where子句只是对我的结构实现特征这一事实的限制。看起来就像T转换为dyn A ,是这样吗?

为什么我想用 <T as T> 强制调用时出现错误当 where约束确保 a存在吗?

我的问题是在更复杂的情况下,函数 a()由我的 block impl SA 中函数的属性宏生成我不知道如何在 impl 之外生成函数阻止并且如果可能的话。是实现整个宏的唯一解决方案impl阻止?

最佳答案

I know that the code is not conventional the function a is not in the impl A for SA but why, in the generic function, it is not the a in SA which is called.

泛型函数 ( foo ) 中的名称解析并不基于调用该函数的具体类型,而是类型和特征在定义处。当编译器处理时

fn foo<T>() where T: A {
T::a();
}

它用来查找的唯一信息aTT实现A 。因此,它相当于 A::a()<T as A>::a() ,调用特征方法。

这不仅仅是一个任意的选择,而是 Rust 设计的一个重要部分——泛型函数的工作原理完全相同,无论任何命名冲突或所使用类型的其他附带细节如何。要了解如果 Rust 工作方式不同,我们如何会收到错误,请考虑以下程序:

trait A {
fn a(x: i32);
}

struct SA {}

impl SA {
fn a(x: &str) {}
}

fn foo<T>() where T: A {
T::a("hello world");
}

特征函数A::a需要 &str ,但是固有的功能SA::a需要 i32 。如果名称解析决定应选择固有函数(如果可用),则 foo::<SA>()即使泛型函数定义本身没问题,也会出现类型错误。这很糟糕,因为这意味着泛型函数可能会仅仅因为类型具有特定的关联函数名称而失败。而且,这将是一个“单态化后错误”——除非在每次使用它的上下文中,否则无法知道泛型函数的定义是否有效(类型检查等)。这会产生难以调试的问题,并且还会减慢编译速度,因为需要更多检查。


为了避免此问题,您应该将固有关联函数视为本质上与特征关联函数位于不同的命名空间中。您不能简单地通过给泛型函数一个匹配的名称来调用固有函数 - 泛型函数调用特征函数(当涉及类型变量时;当然,泛型函数可以调用固有函数相关类型)。

I thought the where was only a constraint on the fact that my struct implement a trait.

确实如此,但问题是您的通用函数永远无法调用固有的 SA::a()除非它明确提到该具体类型。不是where子句隐藏 SA::a() ,但是SA::a() 永远不可能与 T 相关完全没有。

关于generics - 为什么在通用使用时调用特征方法不会调用同名的固有方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73853094/

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