Allow member function which is not member function for the trait?

pub trait TA<Cx> {
    type res;

    fn fun1(&self, cx: Cx) -> Self::res;
}

pub struct SA {
    data: i32,
}

impl<T> TA<T> for SA {
	type res = i32;
	
	fn pre(&self, cx: T) {
		;
	}

	fn fun1(&self, cx: T) -> Self::res {
	        self.pre(cx);
		self.data
	}
}

fn main(){
    
}

The code example is shown above. If the logic of fucn1 is too long to be in one function, how can I divide the function into multiple parts?

It's usually better to ask this sort of "how do I..." question on the users' forum; this one is more for discussing upcoming changes to the language.


You can write the helper functions as private inherent methods of the type, and then use them in the trait implementation:

impl SA {
    /// Helper function for TA<T>::fun1()
    fn pre<T>(&self, cx: T) {
        // ...
    }
}

impl<T> TA<T> for SA {
    type res = i32;
	
    fn fun1(&self, cx: T) -> Self::res {
        self.pre(cx);
        self.data
    }
}
2 Likes

Sorry,i will ask problem in user's forum next time.

As you see, the Helper function also need type T. I want to split func1 to many little function, but cx is involved in most of the content of this function and i can't pass it as parameter in helper function.

You will be able to use T in the helper function. You have to ensure that impl<T> block it's in has matching where clauses and meets the requirement of the trait. But as long as everything is logically correct, there's no limit.

Admittedly it is a bit of complication. For example you can't use Self::res outside of the trait impl, so you'd have to replace it with something like another type parameter U, or a concrete type like i32 that matches the type you used in the trait.

Can you show the code of your approach? thanks a lot. I tried this as following, but couldn't compile it successfully.

The only method I can find is to use PhantomData.

pub struct SA<T> where T:Display {
    data: i32,
    t: PhantomData<T>,
}

impl<T> SA<T> where T:Display{
    fn pre(&self, cx: T) {
		println!("{}", cx);
	}
}

impl<T> TA<T> for SA<T> where T:Display{
	type Res = i32;

	fn fun1(&self, cx: T) -> Self::Res {
	    self.pre(cx);
		self.data
	}
}

but it make SA become generics, and make the code tedious.

Since SA is not generic you have to make the pre function generic over T:

use core::fmt::Debug;
pub trait TA<Cx> where Cx:Debug{
    type res;

    fn fun1(&self, cx: Cx) -> Self::res;
}

pub struct SA {
    data: i32,
}

impl SA {
    fn pre<T>(&self, cx: T) where T: Debug {
		println!("{:?}", cx);
	}
}

impl<T> TA<T> for SA where T: Debug {
	type res = i32;

	fn fun1(&self, cx: T) -> Self::res {
	    self.pre(cx);
		self.data
	}
}
3 Likes

get it , thanks very much.

And based your answer, i also can use trait to constrain the implementation of func1.

use core::fmt::Debug;
pub trait TA<Cx> where Cx:Debug{
    type Res;

    fn fun1(&self, cx: Cx) -> Self::Res;
}

pub struct SA<D> where D: Debug + Clone {
    data: D,
}

trait TB<D> where D: Debug + Clone{
    fn pre1<T>(&self, cx: T) where T: Debug;
    fn pre2(&self) ;
}

impl<D> TB<D> for SA<D> where D: Debug + Clone {
    fn pre1<T>(&self, cx: T) where T: Debug{
        println!("{:?}", cx);
    }
    fn pre2(&self) {
        println!("{:?}", self.data);
    }
}

impl<D,T> TA<T> for SA<D> where T: Debug, D: Debug + Clone {
	type Res = D;

	fn fun1(&self, cx: T) -> Self::Res {
	    self.pre1(cx);
	    self.pre2();
		self.data.clone()
	}
}

fn main(){
    let sa = SA { data: 42 };
    let res = sa.fun1(10);
    println!("{:?}", res);
}

Thx again.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.