问题
I am trying to convert a Python script into Rust as a learning experience and to make the tool faster and shrink the size of the code/executable.
I'm currently trying to convert a section that creates a list of references to methods on self. Now I've learned that there isn't a way to bind the self
variable for a method, one has to use a closure and close over the object that the methods will be called on. However when you create a closure it gets assigned a unique anonymous type, so I don't think I can create a Vec
or array of closures without boxing them, which might be the way to go, but has some overhead that might not be necessary.
What I'm wondering is, instead of the Python informed design of a list of method references, is there a more Rusty way to do this that doesn't fight the type system?
self.dataProcessors = []
if(self.dataMode) :
self.dataProcessors.append(self._processData_)
if(self.csvOn):
self.dataProcessors.append(self._processData_CSV_)
回答1:
To be honest, I’m not sure about a more rusty way, but, yes, you can do it the same way as in Python:
struct Data;
impl Data {
fn foo(&self) {
println!("foo!");
}
fn bar(&self) {
println!("bar!");
}
}
fn main() {
let x: Vec<fn(&Data) -> ()> = vec![Data::foo, Data::bar];
let data = Data;
for f in x {
f(&data);
}
}
Note that this works exactly like in Python: instead of keeping self
, you explicitly pass it as the first argument of the now-function which used to be a method.
Since there is no need to store any values (which would be necessary if you went with closures), basically all you have is a function pointer (of type fn(&Data) -> ()
, which is, well, the type of functions that take Data
and return unit), so its size is known and you don’t need boxing.
来源:https://stackoverflow.com/questions/34980343/what-is-the-idiomatic-way-to-create-a-collection-of-references-to-methods-that-t