【问题标题】:Can I alias fully qualified syntax?我可以给完全限定的语法起别名吗?
【发布时间】:2019-03-10 10:35:59
【问题描述】:

我有一些代码,其中有许多完全限定语法的实例;举个例子:

mod hal {
    pub trait Backend {
        type Device;
    }
}

mod back {
    pub struct Backend {}

    impl ::hal::Backend for Backend {
        type Device = i32;
    }
}

fn main() {
    let d: back::Backend::Device = 0;
}

playground

为了避免如下错误:

error[E0223]: ambiguous associated type
  --> src/main.rs:16:12
   |
16 |     let d: back::Backend::Device = 0;
   |            ^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
   |
   = note: specify the type using the syntax `<back::Backend as Trait>::Device`

有没有一个好方法可以给SomeType as SomeTrait 取别名?然后,只要需要这个完全限定语法的实例,我就可以写:

&lt;S&gt;::associated_fn(...)

请注意,此错误不会发生,因为某些 trait 的定义实际上有多个实现(根据 Rust 编程语言,这是 FQS 应该处理的)。

【问题讨论】:

  • 为什么要从“许多完全限定语法的实例”开始?
  • @Shepmaster 我正在使用一个名为gfx-rs 的库,它有一个名为hal(硬件抽象层)的东西。 hal 确实是一堆 trait,这些 trait 由平台特定的后端(例如 vulkan、directx 等)实现。因此,我经常不得不写&lt;gfx_vulkan::backend::Backend as hal::Backend&gt;::some_fn,以实现某些特定功能。
  • 这些都不能说明为什么你必须使用 FQS 而不是直接调用方法。是否有多个特征定义 some_fn
  • @Shepmaster 这是我对库不太了解的地方,因为在我看来hal 没有实现定义某些关联函数或类型的多个特征......但是,编译器当 FQS 被忽略时,抱怨接收到一个模棱两可的类型。我现在在问题中包含了一个错误示例。
  • @Shepmaster 所以我能够确认错误的发生不是因为某些定义有多个 impl;这是一个重现相同错误的最小示例(由项目 gitter 上的某人提供):play.rust-lang.org/…

标签: syntax rust type-alias


【解决方案1】:

在您的示例中,您可以重命名某些部分,以便以缩写形式引用它们而不会发生冲突:

use hal::Backend;
use back::Backend as BackendImpl;

fn main() {
    let d: <BackendImpl as Backend>::Device = 0;
}

您也可以考虑定义一个类型别名,这样访问起来就不会那么模棱两可了:

mod hal {
    pub trait Backend {
        type Device;
    }
}

mod back {
    pub struct Backend {}
    pub type Device = i32;
    impl ::hal::Backend for Backend {
        type Device = Device;
    }
}

fn main() {
    let d: back::Device = 0;
}

【讨论】:

    【解决方案2】:

    不,没有办法给完全限定的语法起别名。这样做对我来说没有意义,因为这个语法的整个 point 是完全明确的。


    所有这些都假设您实际上需要完全限定的语法。顾名思义,编写代码的方法通常更短。如果没有其他定义 to_string 的特征在范围内并且类型本身没有实现同名的方法,则这些都是等效的:

    <i32 as ToString>::to_string(&42);
    
    ToString::to_string(&42);
    
    i32::to_string(&42);
    
    42.to_string();
    

    另见:

    【讨论】:

    • 所以在 OP 的例子中你可以写 gfx_vulkan::backend::Backend::some_fn(); ?
    • @Rots 不,看起来你不能,我现在已经在问题中添加了一个 MnWE
    • 那个works with functions 但显然没有关联类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 2016-11-14
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多