Почему компилятор Rust недостаточно умен, чтобы обнаружить переменную и функцию с тем же именем? - PullRequest
0 голосов
/ 17 июня 2020

Я пытаюсь получить доступ к функции, передав аргумент, но имя аргумента и функции одинаковы,

fn main(){
    let name = "xyz";
    println!("name: {:?}", name(name));}

fn name(y: &str)-> &str{
    y}

в выводе говорится, что это выражение и требуется функция для разрешения, на самом деле это функцию, и ее можно решить, изменив имя функции, но пока я хочу знать, почему компилятор не обнаруживает функцию?

error[E0618]: expected function, found `&str`
2 |     let name = "xyz";
  |         ---- `&str` defined here
3 |     println!("name: {:?}", name(name));
  |                            ^^^^------
  |                            |
  |                            call expression requires function

Ответы [ 2 ]

2 голосов
/ 17 июня 2020

Я хочу знать, почему компилятор не определяет функцию?

Потому что нечего обнаруживать.

Rust не выделяет функции в отдельное пространство имен, по большей части функция - это просто значение, как и любое другое. Поскольку name может также быть закрытием (которое вызывается) или ссылкой на метод, например,

fn foo() {} // "regular" function
fn main() {
    let foo = foo; // local reference to the function
    let foo = Foo::foo; // UFCS
    let foo = || {}; // anonymous function
}

Фактически, хотя реализация трейтов остается нестабильной, в конечном итоге должно быть возможно сделать что-нибудь в «функцию» (Python называет эту концепцию «вызываемыми») путем реализации черт Fn / FnMut / FnOnce.

1 голос
/ 17 июня 2020

Функция - это переменная. когда вы используете то же имя переменной в новой области видимости, она использует это новое объявление во всей этой области. Итак, в функции main() вы перезаписываете переменную name новым значением "xyz". Ваш код по сути "xyz"("xyz").

В качестве другого примера, что будет печатать этот код?

fn name() {
    println!("hi");
}

fn main() {
    fn name() {
        println!("bye");
    }
    name();
}

Он будет печатать "bye", поскольку он вызывает local function name.

Заметным исключением из этого правила является повторное объявление функции в той же области (будь то верхний уровень или контекст функции):

fn name() {
    println!("a");
}
fn name() {
    println!("b");
}
fn main() {
    fn name() {
        println!("c");
    }
    fn name() {
        println!("d");
    }
    name();
}

Это выдаст вам две ошибки, по одной для каждой области, в которой вы объявили это дважды.

  |
1 | fn name() {
  | --------- previous definition of the value `name` here
...
4 | fn name() {
  | ^^^^^^^^^ `name` redefined here
  |
  = note: `name` must be defined only once in the value namespace of this module

error[E0428]: the name `name` is defined multiple times
  --> src/main.rs:11:5
   |
8  |     fn name() {
   |     --------- previous definition of the value `name` here
...
11 |     fn name() {
   |     ^^^^^^^^^ `name` redefined here
   |
   = note: `name` must be defined only once in the value namespace of this block
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...