With what would I need to replace /* type */
so that o_f
could equal None
, Some(a)
, Some(b)
, or Some(/* a different function with the same signature */)
?
fn func<T: Copy + Ord>(x: &mut Option<Box<Node<T>>>)
{
let mut o_f: /* type */ = None;
let mut result_of_f: Option<bool> = None;
let mut o_b_n_num = Some(Box::new(Node::new(1)));
// ...
if let Some(f) = o_f
{
result_of_f = Some(f(x) && f(&mut o_b_n_num));
}
// ...
}
What you're trying to do is not possible. You have a function generic over T
but internally you're trying to use concrete type i32
. Rust monomorphizes generic functions based on what types they get called with. Take this program for example:
fn func<F, T>(f: F, t: T)
where F: Fn(T)
{
f(t);
}
struct S;
struct R;
fn main() {
func(|x| {}, S);
func(|x| {}, R);
}
Will get compiled to something like:
fn func_S(f: impl Fn(S), s: S)
{
f(s);
}
fn func_R(f: impl Fn(R), r: R)
{
f(r);
}
struct S;
struct R;
fn main() {
func_S(|s| {}, S);
func_R(|r| {}, R);
}
Which is all well and good, but what if we go back and change the first function to this (which is essentially what you're trying to do):
fn func<F, T>(f: F, t: T)
where F: Fn(T)
{
f(t);
f(1); // concrete type i32, not type T
}
struct S;
struct R;
fn main() {
func(|x| {}, S);
func(|x| {}, R);
}
Now it wouldn't compile, but if we imagined it did then it'd like something like this:
fn func_S(f: impl Fn(S), s: S)
{
f(s);
f(1); // error! f expects S not i32
}
fn func_R(f: impl Fn(R), r: R)
{
f(r);
f(1); // error! f expects R not i32
}
struct S;
struct R;
fn main() {
func_S(|s| {}, S);
func_R(|r| {}, R);
}
You see how that makes no sense at all? You're trying to pass a i32
to functions that expect S
and R
.
Now, you have a couple options. If you want some data structure of just i32
s then you don't need to make it generic and can define it just for i32
s. If you want a generic structure where, if some node is missing, and you want populate it with a "default" node (perhaps in the case of Node<i32>
that default node is Node::new(1)
) then you can bind T
on Default
and write something like this:
#[derive(Default)]
struct Node<T: Default>(T);
#[derive(Default)]
struct S;
#[derive(Default)]
struct R;
fn func<F, T>(f: F, t: Option<Node<T>>)
where T: Default, F: Fn(Node<T>)
{
f(t.unwrap_or_default());
}
fn main() {
func(|x| {}, Some(Node(S)));
func(|x| {}, Some(Node(R)));
func(|x: Node<i32>| {}, None);
}
Now your function is truly generic over T
and handles the case of all Node<T>
including Node<i32>
.
See also
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.