2015-09-21 3 views
2

Если тип с плавающей запятой указан в переменной a, то может использоваться функция abs. Следующий пример работает:Что такое тип с плавающей запятой по умолчанию?

fn main() { 
    let a = -1.0f64; 
    println!("{:?}", a.abs()); 
} 

Он печатает 1, как и ожидалось. Но если f64 опущено выдается ошибка во время компиляции, как в следующем примере:

fn main() { 
    let a = -1.0; 
    println!("{:?}", a.abs()); 
} 

Эта версия дает следующие неудачи:

Compiling playground v0.1.0 (file:///C:/git/Rust/playground) 
src\main.rs:3:24: 3:29 error: no method named `abs` found for type `_` in the current scope 
src\main.rs:3  println!("{:?}", a.abs()); 
            ^~~~~ 
note: in expansion of format_args! 
<std macros>:2:25: 2:56 note: expansion site 
<std macros>:1:1: 2:62 note: in expansion of print! 
<std macros>:3:1: 3:54 note: expansion site 
<std macros>:1:1: 3:58 note: in expansion of println! 
src\main.rs:3:5: 3:31 note: expansion site 
src\main.rs:3:24: 3:29 help: items from traits can only be used if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it: 
src\main.rs:3:24: 3:29 help: candidate #1: use `core::num::Float` 
error: aborting due to previous error 
Could not compile `playground`. 

To learn more, run the command again with --verbose. 

Это сообщение говорит тип a является _. Я думаю, что функция abs не может быть использована, потому что неясно, какой именно тип a. Означает ли это, что тип не определен во время компиляции? Что такое используемый тип, если в Rust не указан какой-либо конкретный тип float?

ответ

2

RFC 212 говорит:

Целые литералы, тип которых ничем не ограничена по умолчанию будет i32 [...] с плавающей точкой литералов будет по умолчанию f64.

Однако в большинстве случаев что-то ограничивает предполагаемый тип конкретным типом, например, передавая его методу или помещая его в структуру.

Означает ли это, что тип не определен во время компиляции?

Тип будет всегда будет определен до того, как код фактически выписан. Однако конкретный тип целочисленного или с плавающей запятой вращается в квантовой суперпозиции типов, пока что-то не заставляет его так или иначе. Если ничто не заставляет его, оно возвращается к умолчанию.

Это то, что в конечном счете позволяет код, как это работает:

use std::{f32, f64}; 

fn main() { 
    let a = -1.0; 
    let b = -1.0; 

    println!("{:?}", f32::abs(a)); 
    println!("{:?}", f64::abs(b)); 
} 

Можно было бы ожидать, что если переменная либо f32 или f64, а затем пойти дальше и выбрать один. Я не знаю внутренних компонентов компилятора, чтобы иметь возможность ответить конкретно, но похоже, что резервный тип по умолчанию входит в игру слишком поздно, чтобы сохранить ваш код. Когда поиск метода происходит, он хочет знать тип переменной для поиска действительных совпадений, но пока недоступен.

+2

Почему код OP не компилируется? ([здесь] (https://play.rust-lang.org/?gist=10e4887dbc2efe616cd1&version=stable)) –

+0

Если литералы с плавающей точкой будут по умолчанию 'f64', в приведенном выше коде функция' abs' для 'f64' должна использоваться. Но тип не указан, как предполагает '_' в сообщении об ошибке. – Holger

+0

@ MatthieuM. хороший вопрос. Я не уверен на 100%, но я предполагаю, что порядок операций не позволяет этого. Я отредактировал, чтобы поместить мое текущее предположение. – Shepmaster

Смежные вопросы