-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Closed
Labels
RFCRequest for commentsRequest for comments
Description
Summary
Add a match_class! macro for implementing behavior that varies based on the built-in type of an object.
Detailed Explanation
Doing this currently with downcast is a bit awkward. Because it consumes the Rc,
you have two options:
- Clone the object and then do a series of
ifs.
impl PyFloat {
fn eq(self: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if let Some(i @ PyInt { .. }) = other.clone().downcast() {
Ok(PyInt::new(&self.value + i.as_bigint()).into_ref(vm))
} else if let Some(f @ PyFloat { .. }) = other.downcast() {{
let output = self.value + f.value.to_bigint().unwrap();
Ok(PyFloat::new(output))
} else {
Ok(vm.ctx.not_implemented())
}
}
}- Use the returned
Err(obj)ofdowncastto avoid the clone.
match other.downcast() {
Ok(i @ PyInt { ..}) => {
Ok(PyInt::new(&self.value + ).into_ref(vm))
},
Err(obj) => match obj.downcast() {
Ok(f @ PyFloat { .. }) => {
let output = self.value + f.value.to_bigint().unwrap();
Ok(PyFloat::new(output))
},
_ => Ok(vm.ctx.not_implemented()),
}
}This avoids a pointless clone at the cost of adding undesirable rightward drift. What we really want is to be able to use a match-like syntax that expands to the efficient version above:
impl PyFloat {
fn eq(self: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
match_object!(other,
i @ PyInt { .. } => {
Ok(PyInt::new(&self.value + i.as_bigint()).into_ref(vm))
},
f @ PyFloat { .. } => {
let output = self.value + f.value.to_bigint().unwrap();
Ok(PyFloat::new(output))
},
_ => Ok(vm.ctx.not_implemented()),
)
}
}Drawbacks, Rationale, and Alternatives
The main drawback is that it is another macro. It should be very straightforward to implement and to understand though.
Unresolved Questions
Will allowing a full pattern in each match clause encourage making struct fields public, when they really should not be? An alternative would be to just allow the type name in each match arm.
coolreader18
Metadata
Metadata
Assignees
Labels
RFCRequest for commentsRequest for comments