Can I create an array of functions and pass that to another method?


#1

See my example below (which won’t compile)

<anon>:71:36: 71:41 error: mismatched types:
 expected `fn() {linq2}`,
    found `fn() {linq3}`
(expected fn item,
    found a different fn item) [E0308]
<anon>:71     let restrictions = vec![linq2, linq3];

This is the code:

#[derive(Debug)]
struct Product<'a> {
    id: i32,
    product_name: &'a str,
    units_in_stock: i32,
    unit_price: f32,
}

fn get_product_list<'a>() -> Vec<Product<'a>> {
    
    let p1 = Product { 
        id: 1, 
        product_name: "Chai", 
        units_in_stock: 0,
        unit_price: 2.0,
    };
    
    let p2 = Product { 
        id: 17, 
        product_name: "Alice Mutton", 
        units_in_stock: 2,
        unit_price: 39.000,
    };
    
    return vec![p1, p2];
}


fn linq2() {
    let products: Vec<Product> = get_product_list();
    
    let sold_out_products = products
        .iter()
        .find(|a| { a.units_in_stock == 0 });
    
    println!("Sold out products:");
    for p in sold_out_products {
        println!("{} is sold out!", p.product_name);
    }
}

fn linq3() {
    let products: Vec<Product> = get_product_list();
    
    let expensive_in_stock_products = products
        .iter()
        .find(|a| { a.units_in_stock > 0 && a.unit_price > 3.0 });
    
    println!("In-stock products that cost more than 3.00:");
    for p in expensive_in_stock_products {
        println!("{} is in stock and costs more than 3.00.", p.product_name);
    }
}

fn main() {
    let restrictions = vec![linq2, linq3];
    run_examples(restrictions);
}

fn run_examples<F>(fns : Vec<F>) 
    where F : Fn() {
    
    for f in fns {
        f();
        println!("");
    }
}

#2
    let restrictions: Vec<fn()> = vec![linq2, linq3];

All functions get their own unique “strong” type (specifically, the original name is part of the type). You have to explicitly specify a common “weak” type somewhere; you can either do that as above, or use linq2 as fn().


#3

You can try to use trait objects: http://is.gd/h6WoYU


#4

Awesome I’m glad it’s possible!