< 返回版块

eweca-d 发表于 2024-06-24 20:55

有一个函数接受入参&[S],此时使用S时,实际上是一个引用。而这个引用可以转化为U。该如何写呢?比如接受的可以是&[&[f64]]。或者有没有办法让泛型可以是接收&[&[f64]],&[[f64;2]],&[[f64;3]]呢。

评论区

写评论
作者 eweca-d 2024-06-27 19:56

问题在于,想要得到的是Vec,A是由里面那个生成的。

会变成:

use core::fmt::Debug;

fn main() {
    test(&[&[3f64, 4f64, 5f64, 6f64][..]]); // &[&[f64]]
    test(&[[3f64,4f64]]); // &[[f64;2]]
    test(&[[3f64,4f64,5f64]]); // &[[f64;3]]
}

#[derive(Debug, Clone, Copy)]
struct A {
    x: f64,
    y: f64,
    z: f64
}

impl From<&[f64]> for A {
    fn from(v: &[f64]) -> A {
        assert!(v.len() >= 3);
        A {
            x: v[0],
            y: v[1],
            z: v[2]
        }
    }
}

impl From<[f64; 3]> for A {
    fn from(v: [f64; 3]) -> A {
        A {
            x: v[0],
            y: v[1],
            z: v[2]
        }
    }
}

impl From<[f64; 2]> for A {
    fn from(v: [f64; 2]) -> A {
        A {
            x: v[0],
            y: v[1],
            z: 0.0
        }
    }
}

fn test<Slc: AsRef<[f64]>, I: IntoIterator<Item = Slc>>(it: I)
{
    let mut v: Vec<A> = vec![];
    for slc in it {
        v.extend_from_slice(slc.as_ref().into());
    }
    println!("v: {:?}", v);
}

--
👇
aj3n: ```rust fn main() { foo(&[[1.0, 2.0]]); foo(&[&[1.0, 2.0]]); }

fn foo<Slc: AsRef<[f64]>, I: IntoIterator<Item = Slc>>(it: I) -> Vec { let mut v = vec![]; for slc in it { v.extend_from_slice(slc.as_ref()); } v }


像这样?
作者 eweca-d 2024-06-27 19:50

这个不行的。

use core::fmt::Debug;

fn main() {
    test::<_, A>(&[&[3f64, 4f64, 5f64, 6f64][..]]); // &[&[f64]]
    test::<_, A>(&[[3f64,4f64]]); // &[[f64;2]]
    test::<_, A>(&[[3f64,4f64,5f64]]); // &[[f64;3]]
}

#[derive(Debug)]
struct A {
    x: f64,
    y: f64,
    z: f64
}

impl From<&[f64]> for A {
    fn from(v: &[f64]) -> A {
        assert!(v.len() >= 3);
        A {
            x: v[0],
            y: v[1],
            z: v[2]
        }
    }
}

impl From<[f64; 3]> for A {
    fn from(v: [f64; 3]) -> A {
        A {
            x: v[0],
            y: v[1],
            z: v[2]
        }
    }
}

impl From<[f64; 2]> for A {
    fn from(v: [f64; 2]) -> A {
        A {
            x: v[0],
            y: v[1],
            z: 0.0
        }
    }
}

fn test<S, U: Debug>(s: &[S])
where
    S: Into<U>,
{
    let a: Vec<U> = s.iter().map(|x| x.into()).collect();
    println!("res: {:?}", a);
}

我之前就是遇到这个问题,报错是error[E0277]: the trait bound U: From<&S> is not satisfied.

--
👇
bestgopher: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6b4304122f5e7349c0f5503fe64fbfff

这样呢?

aj3n 2024-06-26 10:39
fn main() {
    foo(&[[1.0, 2.0]]);
    foo(&[&[1.0, 2.0]]);
}

fn foo<Slc: AsRef<[f64]>, I: IntoIterator<Item = Slc>>(it: I) -> Vec<f64> {
    let mut v = vec![];
    for slc in it {
        v.extend_from_slice(slc.as_ref());
    }
    v
}

像这样?

bestgopher 2024-06-25 11:50

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6b4304122f5e7349c0f5503fe64fbfff

这样呢?

作者 eweca-d 2024-06-25 09:20

我的问题,改下,输入是&[[f64;2]]

--
👇
viruscamp: > 或者有没有办法让泛型可以是接收&[f64],&[f64;2],&[f64;3]呢。

&[f64;2] 能隐式转换(coercion) 成 &[f64] 的吧

作者 eweca-d 2024-06-25 09:19

忘了说。。。这个函数的return不带U。。。或许可以拆成两个函数?

--
👇
viruscamp: 这种?

fn slice_to_vec<'a, S, U: From<&'a S>>(a: &'a[S]) -> Vec<U> {
    a.iter()
        .map(|s| s.into())
        .collect()
}

凡是不好写 From 的就写 Into , 反过来也一样。

viruscamp 2024-06-24 23:48

或者有没有办法让泛型可以是接收&[f64],&[f64;2],&[f64;3]呢。

&[f64;2] 能隐式转换(coercion) 成 &[f64] 的吧

viruscamp 2024-06-24 23:35

这种?

fn slice_to_vec<'a, S, U: From<&'a S>>(a: &'a[S]) -> Vec<U> {
    a.iter()
        .map(|s| s.into())
        .collect()
}

凡是不好写 From 的就写 Into , 反过来也一样。

1 共 8 条评论, 1 页