简体   繁体   English

如何在 Rust 函数中返回一个数组

[英]How to return an array in Rust function

I wanted to create a function in Rust that generates an Array of x size with random values.我想在 Rust 中创建一个函数,它生成一个具有随机值的 x 大小的数组。 I would like to ask how to return an array in Rust function and it would be nice if you can check if the rest of my code is ok.我想问一下如何在 Rust 函数中返回一个数组,如果你能检查我的其余代码是否正常,那就太好了。 I am sorry for my basic question but I am a beginner.我很抱歉我的基本问题,但我是初学者。

use rand::prelude::*;

fn generateArray(howManyValues: u32)->[f64]
{
    let mut rng = rand::thread_rng();
    let array: [f64, howManyValues];
    for i in 0..howManyValues
    {
        array[i] = rng.gen()*100;
    }

    println!("{:?}", array);
    return array;
}

fn main() {
    generateArray(10);
}

I want to create a function in Rust that generates an Array of x size with random values我想在 Rust 中创建一个函数,它生成一个具有随机值的 x 大小的数组

The type [f64] is a slice, not an array.类型[f64]是一个切片,而不是一个数组。 An array needs a length, like [f64; 25]数组需要一个长度,例如[f64; 25] [f64; 25] . [f64; 25]

Rust's Vec is probably better than a array or slice for this job, unless you're using some sort of foreign function interface (FFI), or a Rust API requires an array (it probably requires Deref<Target = [T]> , basically generic over all array-like types including Vec and arrays).对于这项工作,Rust 的Vec可能比数组或切片更好,除非您使用某种外部函数接口 (FFI),或者 Rust API 需要一个数组(它可能需要Deref<Target = [T]> ,基本上所有类数组类型的泛型,包括 Vec 和数组)。 Vec is analogous to C++'s std::vector , and Java's ArrayList . Vec类似于 C++ 的std::vector和 Java 的ArrayList

use rand::prelude::*;

fn generate_vec(len: usize) -> Vec<f64> {
    let mut rng = rand::thread_rng();
    let mut vec = Vec::with_capacity(len);
    for _ in 0..len {
        vec.push(rng.gen::<f64>() * 100.);
    }
    return vec;
}

fn main() {
    let generated_vec = generate_vec(10);
    println!("{:?}", generated_vec);
}

I made some style changes[1].我做了一些风格改变[1]。 If you really want an array, read on.如果你真的想要一个数组,请继续阅读。

If you know the size of the array at compile time, you can use an array.如果您在编译时知道数组的大小,则可以使用数组。 But if it is too big to fit on the stack, you'll get a stack overflow.但是如果它太大而无法放入堆栈,则会出现堆栈溢出。

use rand::prelude::*;

const CONST_LEN: usize = 10;

fn generate_array() -> [f64; CONST_LEN] {
    let mut rng = rand::thread_rng();
    let mut arr = [0.; CONST_LEN];
    for item in arr.iter_mut() {
        *item = rng.gen::<f64>() * 100.;
    }
    arr
}

fn main() {
    let generated_array = generate_array();
    println!("{:?}", generated_array);
}

If you don't know the length at compile time, or it is too big to fit on the stack, the closest you can get to an array is Box<[T]> (Box of slice of T) using into_boxed_slice() .如果您在编译时不知道长度,或者它太大而无法放入堆栈,那么最接近数组的是Box<[T]> (T 切片的盒子),使用into_boxed_slice()

use rand::prelude::*;

fn generate_array(len: usize) -> Box<[f64]> {
    let mut rng = rand::thread_rng();
    let mut vec = Vec::with_capacity(len);
    for _ in 0..len {
        vec.push(rng.gen::<f64>() * 100.);
    }
    vec.into_boxed_slice()
}

fn main() {
    let generated_array = generate_array(10);
    println!("{:?}", generated_array);
}

[1] words in function names separated with underscores instead of camelCase, moved println to main() and changed the type of len to usize , since this is how arrays are typically indexed in rust. [1] 函数名称中的单词用下划线而不是驼峰命名法分隔,将println移至main()并将 len 的类型更改为usize ,因为这通常是在 rust 中索引数组的方式。

First like other programming languages array in Rust cannot grow or shrink.首先像其他编程语言一样,Rust 中的数组不能增长或缩小。 You can either use a vector.您可以使用向量。

let v : Vec<i32> = Vec::new();

you can use .push() function to push values in vector.您可以使用 .push() 函数在向量中推送值。

Adapting your function, and still returning an array, requires specifying the number of elements in the return type ie fn generateArray()->[f64; 100]调整您的函数并仍然返回一个数组,需要指定返回类型中的元素数量,即fn generateArray()->[f64; 100] fn generateArray()->[f64; 100] . fn generateArray()->[f64; 100] The rust type system accounts for the size of an array, so [f64; 100] rust 类型系统考虑了数组的大小,所以[f64; 100] [f64; 100] (an array of length 100 containing f64 s) is a different type from [f64; 99] [f64; 100] (包含f64 s 的长度为 100 的数组)与[f64; 99] [f64; 99] . [f64; 99] Specifying the array's length in the function makes is less reusable, as it always returns the same size array.在函数中指定数组的长度会降低可重用性,因为它总是返回相同大小的数组。

If you simply must create stack-allocated arrays full of random floats, you could use a macro, but this limits you to array sizes known at compile time ( constexpr in C++ lingo, const in Rust lingo).如果您只是必须创建充满随机浮点数的堆栈分配数组,您可以使用宏,但这会限制您在编译时已知的数组大小(C++ 术语中的constexpr ,Rust 术语中的const )。 I consider this macro approach slightly unidiomatic rust.我认为这种宏观方法有点单调。 The macro could look like宏可能看起来像

use rand::prelude::*;

macro_rules! make_array {
    ($size:literal) => {{
        let mut rng = rand::thread_rng();
        let mut arr = [0_f64; $size];
        for item in arr.iter_mut() {
            *item = rng.gen::<f64>()*100.;
        }
        arr
    }}
}

fn main() {
    let arr = make_array!(32);
    println!("{:?}", arr);
    let arr = make_array!(16);
    println!("{:?}", arr);
}

This is more reusable than the modified function, as you can specify different numbers of elements.这比修改后的函数更可重用,因为您可以指定不同数量的元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM