What types are valid for the `self` parameter of a

2019-01-12 04:01发布

I wanted to create a method that only works where the self parameter was an Rc. I saw that I could use Box, so I thought I might try to mimic how that works:

use std::rc::Rc;
use std::sync::Arc;

struct Bar;

impl Bar {
    fn consuming(self) {}
    fn reference(&self) {}
    fn owned(self: Box<Bar>) {}
    fn ref_count(self: Rc<Bar>) {}
    fn atomic_ref_count(self: Arc<Bar>) {}
}

fn main() {}

Yields these errors:

error[E0308]: mismatched method receiver
  --> src/main.rs:10:18
   |
10 |     fn ref_count(self: Rc<Bar>) {}
   |                  ^^^^ expected struct `Bar`, found struct `std::rc::Rc`
   |
   = note: expected type `Bar`
   = note:    found type `std::rc::Rc<Bar>`

error[E0308]: mismatched method receiver
  --> src/main.rs:11:25
   |
11 |     fn atomic_ref_count(self: Arc<Bar>) {}
   |                         ^^^^ expected struct `Bar`, found struct `std::sync::Arc`
   |
   = note: expected type `Bar`
   = note:    found type `std::sync::Arc<Bar>`

This is with Rust 1.13, and you can also see it in the playpen

标签: rust
2条回答
可以哭但决不认输i
2楼-- · 2019-01-12 04:14

It's now possible to use arbitrary types for self, including Arc<Self>, but the feature is considered unstable and thus requires adding this crate attribute:

#![feature(arbitrary_self_types)]

Using feature crate attributes requires using nightly Rust.

查看更多
地球回转人心会变
3楼-- · 2019-01-12 04:17

At the moment, these are the valid ones:

struct Foo;

impl Foo {
    fn by_val(self: Foo) {} // aka by_val(self)
    fn by_ref(self: &Foo) {} // aka by_ref(&self)
    fn by_mut_ref(self: &mut Foo) {} // aka by_mut_ref(&mut self)
    fn by_box(self: Box<Foo>) {} // no short form
}

fn main() {}

Until recently, Rust didn't have this explicit self form, only self, &self, &mut self and ~self (the old name for Box). This changed so that only by-value and by-references have the short-hand built-in syntax, since they are the common cases, and have very key language properties, while all smart pointers (including Box) require the explicit form.

However, the impl handling hasn't been generalised to match the syntax, meaning non-Box pointers still don't work. I believe it requires so-called 'trait reform' which has yet to be implemented.

Current discussion is taking place in issue 44874.

(Something to look forward to!)

查看更多
登录 后发表回答