masoud
masoud

Reputation: 56529

No method/field name found

I'm trying to apply some OOP but I'm facing a problem.

use std::io::Read;

struct Source {
    look: char
}

impl Source {
    fn new() {
        Source {look: '\0'};
    }

    fn get_char(&mut self) {
        self.look = 'a';
    }
}


fn main() {
    let src = Source::new();
    src.get_char();

    println!("{}", src.look);
}

Compiler reports these errors, for src.get_char();:

error: no method named get_char found for type () in the current scope

and for println!("{}", src.look);:

attempted access of field look on type (), but no field with that name was found

I can't find out what I've missed.

Upvotes: 2

Views: 1803

Answers (1)

Matthieu M.
Matthieu M.

Reputation: 300219

Source::new has no return type specified, and thus returns () (the empty tuple, also called unit).

As a result, src has type (), which does not have a get_char method, which is what the error message is telling you.

So, first things first, let's set a proper signature for new: fn new() -> Source. Now we get:

error: not all control paths return a value [E0269]
     fn new() -> Source {
         Source {look: '\0'};
     }

This is caused because Rust is an expression language, nearly everything is an expression, unless a semicolon is used to transform the expression into a statement. You can write new either:

fn new() -> Source { 
    return Source { look: '\0' };
}

Or:

fn new() -> Source {
    Source { look: '\0' }  // look Ma, no semi-colon!
}

The latter being the more idiomatic in Rust.

So, let's do that, now we get:

error: cannot borrow immutable local variable `src` as mutable
    src.get_char();
    ^~~

Which is because src is declared immutable (the default), for it to be mutable you need to use let mut src.

And now it all works!


Final code:

use std::io::Read;

struct Source {
    look: char
}

impl Source {
    fn new() -> Source {
        Source {look: '\0'}
    }

    fn get_char(&mut self) {
        self.look = 'a';
    }
}

fn main() {
    let mut src = Source::new();
    src.get_char();

    println!("{}", src.look);
}

Note: there is a warning because std::io::Read is unused, but I assume you plan to use it.

Upvotes: 8

Related Questions