从特征实现静态方法时的名称解析错误

时间:2014-05-15 09:40:11

标签: methods static rust traits

以下是教程中的略微修改示例:

use std::f64::consts::PI;

trait Awesome {
  fn how_awesome() -> int;
}

struct Circle { radius: f64 }
impl Circle {
    fn area(&self) -> f64 { self.radius * self.radius * PI }
    fn new(area: f64) -> Circle { Circle { radius: (area / PI).sqrt() } }
}


impl Awesome for Circle {
    fn how_awesome() -> int { 5 }
}

fn main() {
    let c = Circle::new(42.5); // fine
    let c2 = Circle::how_awesome(); // error: unresolved name `Circle::how_awesome`.
}

它可能比这更奇怪:

struct Point {
  x: f64,
  y: f64
}

impl Awesome for Point {
    fn how_awesome() -> int { 3 }
}

fn main() {
    let p = Point::how_awesome();
}

结果

ERROR:rustc::middle::resolve: !!! (resolving module in lexical scope) module wasn't actually a module!
type.rs:41:11: 41:25 error: unresolved name
type.rs:41   let p = Point::how_awesome();
                     ^~~~~~~~~~~~~~
type.rs:41:11: 41:25 error: use of undeclared module `Point`
type.rs:41   let p = Point::how_awesome();
                     ^~~~~~~~~~~~~~
ERROR:rustc::middle::resolve: !!! (resolving module in lexical scope) module wasn't actually a module!
type.rs:41:11: 41:25 error: unresolved name `Point::how_awesome`.
type.rs:41   let p = Point::how_awesome(); 
                     ^~~~~~~~~~~~~~

我每晚使用相当新鲜:

rustc 0.11.0-pre-nightly (db5ca23 2014-05-14 01:06:24 -0700)
host: x86_64-unknown-linux-gnu

搜索此问题绝对没有任何内容。

1 个答案:

答案 0 :(得分:3)

目前,所有方法都有其特征,包括静态方法。在实施uniform function call syntax (UFCS)之前,您需要在特征上调用它们:

let p = Awesome::how_awesome();

但是,编译器需要某种方法来确切地确定应该使用该特征的哪个实现,即某种方式来推断for的RHS上的类型以找到特定的impl。如上所述,how_awesome方法根本没有提到这个Self类型,因此编译器无法推断它(就像使用the default method of the Default trait一样,它可以像let x: Type = Default::default();)。

应该有办法手动指定它,但我们目前没有。这也是UFCS RFC所涵盖的内容,目前唯一可以解决的问题是:

struct Point {
  x: f64,
  y: f64
}

trait Awesome {
    fn how_awesome(_ignored: Option<Self>) -> int;
}

impl Awesome for Point {
    fn how_awesome(_ignore: Option<Point>) -> int { 0 }
}

fn main() {
    let p = Awesome::how_awesome(None::<Point>);
}

我已就Point::how_awesome的丑陋错误提交了#14225