Приведение не может быть выполнено во время разрушения типа. Это потому, что вы не можете аннотировать тип, который будет содержаться в типе, который вы разрушаете, поэтому он не зависит от вас, а вместо этого от типа, который подвергается деструктурированию. Например:
struct Point {
x: f32,
y: f32,
}
let myOtherPoint = Point { x: 0, y: 0 };
let Point {x, y} = myOtherPoint;
Типы x
и y
определяются типом Point
. С другой стороны, это можно изменить в случае кортежей и массивов:
fn main() {
let [x, y, z]: [f32; 3] = [1.2, 2.3, 3.4];
let (x, y, z): (usize, f32, String) = (1, 2.3, "3.4".into());
}
Это в основном из-за аннотаций типов, необходимых для кортежей при написании сигнатур функций:
fn foo((a, b, c): (usize, f32, String)) {}
Но это только потому, что кортежи сами по себе не являются именованными типами, поэтому существует необходимость именовать кортеж, аннотируя тип. С другой стороны, struct
s и enum
s названы и поэтому разрушаемы.
Решение вашей конкретной проблемы описано в теле, а не в заголовке:
Используйте отдельную переменную с затенением, чтобы сохранить удобство использования. Также обратите внимание, что типы с плавающей запятой (f32
и f64
) не могут быть переполнены ( Они имеют бесконечность ), только целые числа ([u, i][size, 8, 16, 32, 64, 128]
).
fn area(x: Rectangle) -> f64 {
// Here's where I'd like have type annotations
// while doing destructuring assignment:
let Rectangle {
p1: Point { x: x1, y: y1 },
p2: Point { x: x2, y: y2 },
} = rect;
let (x1, x2, y1, y2) = (x1 as f64, x2 as f64,
y1 as f64, y2 as f64);
((x2 - x1) * (y2 - y1)).abs()
}