如何将Rust中的特性放入数组类型的函数类型中?

huangapple go评论84阅读模式
英文:

How to put traits in Rust's function types in an array's type?

问题

我正在尝试创建一个函数数组来对数字进行排序,但在声明数组的类型时遇到了问题。我无法使数组的元素类型通用化,以便可以传入实现了OrdCopy特性的类型,而不仅仅是u32

如何使数组 sorts 包含的函数的第一个参数只需要实现 OrdCopy 特性,而不限定为 u32

// 当前的代码。请注意 fn(&mut [u32])
let sorts: [(&'static str, fn(&mut [u32])); 6] = [
    ("Insertion sort", insertion_sort),
    ("Selection sort", selection_sort),
    ("Bubble sort", bubble_sort),
    ("Merge sort", merge_sort),
    ("Quick sort", quick_sort),
    ("Heap sort", heap_sort),
];

fn insertion_sort(array: &mut [impl Ord + Copy]) { }
fn selection_sort(array: &mut [impl Ord + Copy]) { }
fn bubble_sort(array: &mut [impl Ord + Copy]) { }
fn merge_sort(array: &mut [impl Ord + Copy]) { }
fn quick_sort(array: &mut [impl Ord + Copy]) { }
fn heap_sort(array: &mut [impl Ord + Copy]) { }

// 我想要实现的代码。请注意 fn(&mut [impl Ord + Copy])
let sorts: [(&'static str, fn(&mut [impl Ord + Copy])); 6] = [
    ("Insertion sort", insertion_sort),
    ("Selection sort", selection_sort),
    ("Bubble sort", bubble_sort),
    ("Merge sort", merge_sort),
    ("Quick sort", quick_sort),
    ("Heap sort", heap_sort),
];

我想要这样做的原因是,这样我就不需要在将它们应用于不同类型的数字数组时更改排序函数数组的类型。

编辑: 我想要实现的目标如下。基本上,我想通过依次将它们应用于之前定义的数组来轻松测试不同的排序实现。sorts 数组的使用方式如下,包括由 syskov 提供的答案。

fn main() {
    let problem: [u8; 32] = rand::random();
    fn create_sorts<T: Ord + Copy>() -> [(&'static str, fn(&mut [T])); 7] {
        [
            ("Insertion sort", insertion_sort),
            ("Selection sort", selection_sort),
            ("Bubble sort", bubble_sort),
            ("Merge sort", merge_sort),
            ("Quick sort", quick_sort),
            ("Heap sort", heap_sort),
            ("Stooge sort", stooge_sort),
        ]
    }

    println!("{:?}", problem);
    for (name, sort) in create_sorts().iter() {
        let mut problem_ = problem.clone();

        let now = Instant::now();
        sort(&mut problem_);
        let elapsed = now.elapsed();

        let judgment: &str = match is_sorted(&problem_) {
            true => "",
            false => "",
        };

        println!("{} in {:?}: {}", judgment, elapsed, name);
    }
}
英文:

I'm trying to create an array of functions that sort numbers, but am having issues with the declaring the array's type. I can't get it to be generic over the input parameter of the functions.

How do I accomplish that the array sorts has functions whose first and only parameter only require implementing the traits Ord and Copy instead of being u32?

// What I have now. Note the fn(&mut [u32])
let sorts: [(&'static str, fn(&mut [u32])); 6] = [
    ("Insertion sort", insertion_sort),
    ("Selection sort", selection_sort),
    ("Bubble sort", bubble_sort),
    ("Merge sort", merge_sort),
    ("Quick sort", quick_sort),
    ("Heap sort", heap_sort),
];

fn insertion_sort(array: &mut [impl Ord + Copy]) { }
fn selection_sort(array: &mut [impl Ord + Copy]) { }
fn bubble_sort(array: &mut [impl Ord + Copy]) { }
fn merge_sort(array: &mut [impl Ord + Copy]) { }
fn quick_sort(array: &mut [impl Ord + Copy]) { }
fn heap_sort(array: &mut [impl Ord + Copy]) { }

// What I want to accomplish. Note the fn(&mut [impl Ord + Copy])
let sorts: [(&'static str, fn(&mut [impl Ord + Copy])); 6] = [
    ("Insertion sort", insertion_sort),
    ("Selection sort", selection_sort),
    ("Bubble sort", bubble_sort),
    ("Merge sort", merge_sort),
    ("Quick sort", quick_sort),
    ("Heap sort", heap_sort),
];

The reason I would like to do this is so that I don't need to change the type of the sorting functions array when apply them to an array of numbers of a different type.

EDIT: What I want to accomplish is the following. Basically I want to test different sorting implementations easily by applying them in turn to an array defined earlier. The sorts array is used as follows, including the answer as provided by syskov.

fn main() {
    let problem: [u8; 32] = rand::random();
    fn create_sorts<T: Ord + Copy>() -> [(&'static str, fn(&mut [T])); 7] {
        [
            ("Insertion sort", insertion_sort),
            ("Selection sort", selection_sort),
            ("Bubble sort", bubble_sort),
            ("Merge sort", merge_sort),
            ("Quick sort", quick_sort),
            ("Heap sort", heap_sort),
            ("Stooge sort", stooge_sort),
        ]
    }

    println!("{:?}", problem);
    for (name, sort) in create_sorts().iter() {
        let mut problem_ = problem.clone();

        let now = Instant::now();
        sort(&mut problem_);
        let elapsed = now.elapsed();

        let judgment: &str = match is_sorted(&problem_) {
            true => "✓",
            false => "✗",
        };

        println!("{} in {:?}: {}", judgment, elapsed, name);
    }
}

答案1

得分: 3

I don't know exactly context when sorts is used, but you can have some sort of generic function it based on numbers array you sort. It would reduce boilerplate.

fn main () {
    fn insertion_sort(array: &mut [impl Ord + Copy]) { }
    fn selection_sort(array: &mut [impl Ord + Copy]) { }
    fn bubble_sort(array: &mut [impl Ord + Copy]) { }
    fn merge_sort(array: &mut [impl Ord + Copy]) { }
    fn quick_sort(array: &mut [impl Ord + Copy]) { }
    fn heap_sort(array: &mut [impl Ord + Copy]) { }

    fn create_sorts<T: Ord + Copy>() -> [(&'static str, fn(&mut [T])); 6] {
        [
            ("Insertion sort", insertion_sort),
            ("Selection sort", selection_sort),
            ("Bubble sort", bubble_sort),
            ("Merge sort", merge_sort),
            ("Quick sort", quick_sort),
            ("Heap sort", heap_sort),
        ]
    }

    let sorts_u32 = create_sorts::<u32>();
    let sorts_u64 = create_sorts::<u64>();
}
英文:

I don't know exactly context when sorts is used, but you can have some sort of generic function it based on numbers array you sort. It would reduce boilerplate.

fn main () {
    fn insertion_sort(array: &amp;mut [impl Ord + Copy]) { }
    fn selection_sort(array: &amp;mut [impl Ord + Copy]) { }
    fn bubble_sort(array: &amp;mut [impl Ord + Copy]) { }
    fn merge_sort(array: &amp;mut [impl Ord + Copy]) { }
    fn quick_sort(array: &amp;mut [impl Ord + Copy]) { }
    fn heap_sort(array: &amp;mut [impl Ord + Copy]) { }

    fn create_sorts&lt;T: Ord + Copy&gt;() -&gt; [(&amp;&#39;static str, fn (&amp;mut [T])); 6] {
        [
            (&quot;Insertion sort&quot;, insertion_sort),
            (&quot;Selection sort&quot;, selection_sort),
            (&quot;Bubble sort&quot;, bubble_sort),
            (&quot;Merge sort&quot;, merge_sort),
            (&quot;Quick sort&quot;, quick_sort),
            (&quot;Heap sort&quot;, heap_sort),
        ]
    }

    let sorts_u32 = create_sorts::&lt;u32&gt;();
    let sorts_u64 = create_sorts::&lt;u64&gt;();
}

答案2

得分: 1

你需要有一个通用的函数或结构来存储你的数组。类似以下示例。

fn dumb<T>() 
where T: Ord + Copy
{

    // 我想要实现的内容。注意这里的 fn(&mut [impl Ord + Copy])
    let sorts: [(&'static str, fn(&mut [T])); 6] = [
        ("Insertion sort", insertion_sort),
        ("Selection sort", selection_sort),
        ("Bubble sort", bubble_sort),
        ("Merge sort", merge_sort),
        ("Quick sort", quick_sort),
        ("Heap sort", heap_sort),
    ];
    
}
struct Sorts<T> 
where T: Ord + Copy
{
    sorts: [(&'static str, fn(&mut [T])); 6]
}

impl<T> Sorts<T> 
where T: Ord + Copy
{

    pub fn new() -> Self {
        Sorts {
            sorts: [
                ("Insertion sort", insertion_sort),
                ("Selection sort", selection_sort),
                ("Bubble sort", bubble_sort),
                ("Merge sort", merge_sort),
                ("Quick sort", quick_sort),
                ("Heap sort", heap_sort),
            ]
        }
    }

}
英文:

You need to have a generic function or struct to store your array. Something similar to examples below.

fn dumb&lt;T&gt;() 
where T : Ord + Copy
{

    // What I want to accomplish. Note the fn(&amp;mut [impl Ord + Copy])
    let sorts: [(&amp;&#39;static str, fn(&amp;mut [T])); 6] = [
        (&quot;Insertion sort&quot;, insertion_sort),
        (&quot;Selection sort&quot;, selection_sort),
        (&quot;Bubble sort&quot;, bubble_sort),
        (&quot;Merge sort&quot;, merge_sort),
        (&quot;Quick sort&quot;, quick_sort),
        (&quot;Heap sort&quot;, heap_sort),
    ];
    
}

struct Sorts&lt;T&gt; 
where T : Ord + Copy
{
    sorts : [(&amp;&#39;static str, fn(&amp;mut [T])); 6]
}

impl&lt;T&gt; Sorts&lt;T&gt; 
where T : Ord + Copy
{

    pub fn new() -&gt; Self {
        Sorts {
            sorts : [
                (&quot;Insertion sort&quot;, insertion_sort),
                (&quot;Selection sort&quot;, selection_sort),
                (&quot;Bubble sort&quot;, bubble_sort),
                (&quot;Merge sort&quot;, merge_sort),
                (&quot;Quick sort&quot;, quick_sort),
                (&quot;Heap sort&quot;, heap_sort),
            ]
        }
    }

}

huangapple
  • 本文由 发表于 2020年1月3日 18:29:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/59576952.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定