Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a function with a generic fixed-length array? [duplicate]

Tags:

generics

rust

Take an operation on arrays, squaring the length for example.

It's useful to have a generic type (such as f32, f64), but you may also want a generic length, but not a dynamic length.

Here is an example of a squared function that takes 2 arguments.

use std::ops::{Add, AddAssign, Sub, Mul};

const CAN_THIS_BE_GENERIC: usize = 2;

fn squared_length<T>(
    a: &[T; CAN_THIS_BE_GENERIC],
    b: &[T; CAN_THIS_BE_GENERIC]
) -> T
    where T:
        Copy +
        Add +
        AddAssign +
        Add<Output=T> +
        Sub<Output=T> +
        Mul<Output=T>
{
    let mut d: T = a[0] - a[0];  // zero :(
    for (elem_a, elem_b) in a.iter().zip(b.iter()) {
        let elem_dim: T = *elem_a - *elem_b;
        d += elem_dim * elem_dim;
    }
    return d;
}

fn main() {
    println!("Length A! {}", squared_length::<f64>(&[0.5, 3.5], &[10.0, 0.0]));
    println!("Length B! {}", squared_length::<i32>(&[10, -6], &[4, 8]));
    println!("Length C! {}", squared_length::<f32>(&[-3.0, 0.0], &[9.0, 0.0]));
}

Currently the vector length is set at 2.

Is it possible to define generic functions where the size is not dynamic, but generic, the same way types can be generic?

like image 871
ideasman42 Avatar asked Aug 14 '16 09:08

ideasman42


People also ask

How do you create an array of fixed lengths?

Use a tuple to declare an array with fixed length in TypeScript, e.g. const arr: [string, number] = ['a', 1] . Tuple types allow us to express an array with a fixed number of elements whose types are known, but can be different. Copied! We declared a tuple with 3 elements with types of string , number and number .

How do I declare a fixed size array in TypeScript?

To declare a fixed length array in TypeScript, we can use the Array constructor or create a tuple. const arr = new Array<number>(3); const tuple: [number, number, number] = [1, 2, 3]; to create the arr array which is an array of numbers with new Array<number>(3) .

How do you fix the size of an array?

Size of an array If you create an array by initializing its values directly, the size will be the number of elements in it. Thus the size of the array is determined at the time of its creation or, initialization once it is done you cannot change the size of the array.

What is a fixed length array?

A fixed array (also called a fixed length array or fixed size array) is an array where the length is known at compile time. When testScore is instantiated, 30 integers will be allocated. Array elements and subscripting. Each of the variables in an array is called an element. Elements do not have their own unique names.


2 Answers

No, it's not possible as of Rust 1.25. (May 2018). This (often called "type level integers") is a long requested feature, but it's not yet available in Rust.

There have been several RFCs on this topic. Recently, one finally got accepted: RFC 2000 -- Const Generics. However, it is not implemented yet (tracking issue). I would expect implementation to land end 2018 earliest, but more likely 2019.

There are a few crates simulating type level integers like type-num. It's kind of usable, but I wouldn't call it a full alternative.

Please also note: sometimes it's not really necessary to use type level integer. Your example would work with dynamic sizes, too. Better even: because your function is so small, it's likely to be inlined and then the optimizer can probably figure out all sizes at compile time. So if performance was the only reason to use type level integers, it might not be necessary.

like image 80
Lukas Kalbertodt Avatar answered Oct 19 '22 03:10

Lukas Kalbertodt


First, there are many many APIs for which type-level numbers feel tempting, but you'd increase flexibility by instead using associated types more directly.

That said..

There is a generic-array crate that can almost do this right now, using the aforementioned type-num, but it's gets kinda messy, but should do what you want here. I avoid it myself though.

There is language level progress towards this in both rfcs and the compiler, as well as ongoing discussion around full const-dependent types. I'd therefore kinda expect the generic-array crate to be deprecated in the not too distant future.

like image 22
Jeff Burdges Avatar answered Oct 19 '22 04:10

Jeff Burdges