Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 mutable_reference(&mut self) {}     fn boxed(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   --> a.rs:11:18    | 11 |     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   --> a.rs:12:25    | 12 |     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.15.1.

like image 417
Shepmaster Avatar asked Aug 23 '14 14:08

Shepmaster


People also ask

What type of parameter is self?

The self parameter is a reference to the current instance of the class, and is used to access variables that belongs to the class.

What should be in a self parameter Python?

The self is used to represent the instance of the class. With this keyword, you can access the attributes and methods of the class in python. It binds the attributes with the given arguments. The reason why we use self is that Python does not use the '@' syntax to refer to instance attributes.

What type of variable is self in Python?

The self variable is used to represent the instance of the class which is often used in object-oriented programming. It works as a reference to the object. Python uses the self parameter to refer to instance attributes and methods of the class.

What is self used for in Python?

The self keyword is used to represent an instance (object) of the given class. In this case, the two Cat objects cat1 and cat2 have their own name and age attributes. If there was no self argument, the same class couldn't hold the information for both these objects.

Do you have a method with self as the first parameter?

If you have been programming in Python (object-oriented programming) for some time, then you have definitely come across methods that have self as their first parameter. Let us first try to understand what this recurring self parameter is. What is self in Python?

What is the use of self parameter in Python?

All instance methods take the first parameter self and the value of self is automatically given by Python. The parameter self, similar to a pointer in C language, references to the current object of the class. Using self, instance methods can access and alter the state/attributes of an object.

Why do our two class methods have a common parameter CLS?

Our two class methods have a common parameter cls. All class methods take the first parameter cls. The parameter cls references to the Class. Since cls parameter references to the class, it can access and modify only the class state.

What is self argument in Python?

Self is the first argument to be passed in Constructor and Instance Method. Self must be provided as a First parameter to the Instance method and constructor. If you don’t provide it, it will cause an error. Self is a convention and not a Python keyword . self is parameter in Instance Method and user can use another parameter name in place of it.


Video Answer


2 Answers

Before Rust 1.33, there are only four valid method receivers:

struct Foo;  impl Foo {     fn by_val(self: Foo) {} // a.k.a. by_val(self)     fn by_ref(self: &Foo) {} // a.k.a. by_ref(&self)     fn by_mut_ref(self: &mut Foo) {} // a.k.a. by_mut_ref(&mut self)     fn by_box(self: Box<Foo>) {} // no short form }  fn main() {} 

Originally, 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.

As of Rust 1.33, some additional selected types are available for use as self:

  • Rc
  • Arc
  • Pin

This means that the original example now works:

use std::{rc::Rc, sync::Arc};  struct Bar;  impl Bar {     fn consuming(self)                  { println!("self") }     fn reference(&self)                 { println!("&self") }     fn mut_reference(&mut self)         { println!("&mut self") }     fn boxed(self: Box<Bar>)            { println!("Box") }     fn ref_count(self: Rc<Bar>)         { println!("Rc") }     fn atomic_ref_count(self: Arc<Bar>) { println!("Arc") } }  fn main() {     Bar.consuming();     Bar.reference();     Bar.mut_reference();     Box::new(Bar).boxed();     Rc::new(Bar).ref_count();     Arc::new(Bar).atomic_ref_count(); } 

However, the impl handling hasn't yet been fully generalised to match the syntax, so user-created types still don't work. Progress on this is being made under the feature flag arbitrary_self_types and discussion is taking place in the tracking issue 44874.

(Something to look forward to!)

like image 198
huon Avatar answered Oct 20 '22 11:10

huon


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.

like image 40
jbg Avatar answered Oct 20 '22 10:10

jbg