在 Rust 中将 {integer} 转换为 f32 [英] Converting {integer} to f32 in Rust

查看:69
本文介绍了在 Rust 中将 {integer} 转换为 f32的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将一个值从 {integer} 转换为 f32:

I want to convert a value from {integer} to f32:

struct Vector3 {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}

for x in -5..5 {
    for y in -5..5 {
        for z in -5..5 {
            let foo: Vector3 = Vector3 { x: x, y: y, z: z };
            // do stuff with foo
        }
    }
}

编译器因类型不匹配错误而窒息(期望 f32 但得到 {integer}).不幸的是,我不能简单地更改 Vector3.我正在用这个来提供 C-API.

The compiler chokes on this with a type mismatch error (expecting f32 but getting {integer}). Unfortunately I can not simply change Vector3. I'm feeding a C-API with this.

有什么简单简洁的方法可以将 xyz{integer} 转换f32?

Is there any easy and concise way I can convert x, y and z from {integer} to f32?

我猜没有从 i32{integer}f32 的内置转换,因为在某些情况下它可能是有损的.但是,在我的情况下,我使用的范围很小,这不会成为问题.所以我想告诉编译器无论如何都要转换这个值.

I guess there is no builtin conversion from i32 or {integer} to f32 because it could be lossy in certain situations. However, in my case the range I'm using is so small that this wouldn't be an issue. So I would like to tell the compiler to convert the value anyways.

有趣的是,以下工作:

for x in -5..5 {
    let tmp: i32 = x;
    let foo: f32 = tmp as f32;
}

我使用了很多,只有一个 foo 和一个 x 所以这很快就变得很可怕.

I'm using a lot more that just one foo and one x so this turns hideous really fast.

此外,这有效:

for x in -5i32..5i32 {
    let foo: f32 = x as f32;
    // do stuff with foo here
}

但是我的用例变成了:

for x in -5i32..5i32 {
    for y in -5i32..5i32 {
        for z in -5i32..5i32 {
            let foo: Vector3 = Vector3 {
                x: x as f32,
                y: y as f32,
                z: z as f32,
            };
            // do stuff with foo
        }
    }
}

我认为这对于一个简单的转换来说是非常难以理解的,而且是不合理的.

Which I think is pretty unreadable and an unreasonable amount of cruft for a simple conversion.

我在这里遗漏了什么?

推荐答案

我不知道你为什么觉得在使用 as 时需要指定 i32,因为这工作正常(playground):

I'm not sure why you felt the need to specify the i32s when using as, since this works fine (playground):

for x in -5..5 {
    for y in -5..5 {
        for z in -5..5 {
            let foo = Vector3 { // no need to specify the type of foo
                x: x as f32,
                y: y as f32,
                z: z as f32,
            };
            // etc.
        }
    }
}

正如 Klitos Kyriacou 的回答所观察到的,不存在 {integer} 这样的类型;编译器给出该错误消息是因为它无法推断 x 的具体类型.这实际上并不重要,因为在 Rust 中没有从整数类型到浮点类型的隐式转换,或者从整数类型到其他整数类型的隐式转换,就此而言.事实上,Rust 对任何类型的隐式转换都很短(最显着的例外是 Deref 强制转换).

As Klitos Kyriacou's answer observes, there is no such type as {integer}; the compiler gives that error message because it couldn't infer a concrete type for x. It doesn't actually matter, because there are no implicit conversions from integer types to floating-point types in Rust, or from integer types to other integer types, for that matter. In fact, Rust is quite short on implicit conversions of any sort (the most notable exception being Deref coercions).

as 转换类型允许编译器协调类型不匹配,它最终会用 i32 填充 {integer} (无约束的整数文字总是默认为 i32,在这种情况下,具体类型并不重要).

Casting the type with as permits the compiler to reconcile the type mismatch, and it will eventually fill in {integer} with i32 (unconstrained integer literals always default to i32, not that the concrete type matters in this case).

您可能更喜欢的另一个选项,尤其是当您在循环中将 xyz 用于其他目的时,是隐藏它们使用 f32 版本而不是创建新名称:

Another option you may prefer, especially if you use x, y and z for other purposes in the loop, is to shadow them with f32 versions instead of creating new names:

for x in -5..5 {
    let x = x as f32;
    for y in -5..5 {
        let y = y as f32;
        for z in -5..5 {
            let z = z as f32;
            let foo = Vector3 { x, y, z };
            // etc.
        }
    }
}

(你不必写 x: x, y: y, z: z —— 当变量名与结构成员名相同时,Rust 会做正确的事情.)

(You don't have to write x: x, y: y, z: z -- Rust does the right thing when the variable name is the same as the struct member name.)

另一种选择(最后一个,我保证)是使用 map:

Another option (last one, I promise) is to convert the iterators instead using map:

for x in (-5..5).map(|x| x as f32) {
    for y in (-5..5).map(|y| y as f32) {
        for z in (-5..5).map(|z| z as f32) {
            let foo = Vector3 { x, y, z };
            // etc.
        }
    }
}

然而,它比以前的版本更密集,可能更难阅读.

However it is a little more dense and may be harder to read than the previous version.

这篇关于在 Rust 中将 {integer} 转换为 f32的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆