-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor with_
and add new set_
method for vector types
#597
base: main
Are you sure you want to change the base?
Conversation
Usually I've seen and expect These are all copy types anyway. The existing |
I don't think the current Current: /// Creates a 3D vector from `self` with the given value of `x`.
#[inline]
#[must_use]
pub fn with_x(mut self, x: f32) -> Self {
self.x = x;
self
} New: /// Returns a new version of this 3D vector with the given `x` value.
#[inline]
#[must_use]
pub fn with_x(&self, x: f32) -> Self {
Self { x, ..*self }
} I think both methods are pretty useful. The new // set_ method is better for initializing
let foo = Vec3::ZERO
.set_x(1.0);
// with_ method is better for cloning
let bar = foo.with_y(1.0);
let x = foo.with_z(1.0);
|
Yes, it creates a copy. That's what #[test]
fn vec3_copy() {
let a = Vec3::splat(1.0);
let b = a.with_x(2.0);
assert_eq!(1.0, a.x);
assert_eq!(2.0, b.x);
} |
Ah, sorry for the misunderstanding, I though you meant create a copy as in creating a new instance with the same value (with the modified field x, y, z, etc.).
Yeah, that is for the |
Your desired behavior for the way it works is how it already works. Look at the example unit test that I posted. The current |
Ah, I didn't understand how it work originally, thank you for explaining it. If both methods work, I think it would be better to explicitly create a copy instead of implicitly via the |
I don't understand why you want to create |
The let mut foo = Vec3::ZERO;
// which allows for method chaining pattern
let modified_foo = foo
.set_x(2.0)
.set_y(3.0);
// instead of multiple statements
foo.x = 2.0;
foo.y = 3.0;
let modified_foo = foo; It can also be used along with its swizzle variant ( |
From your opening statement:
The suggested behavior is the actual behavior. It returns a modified copy without modifying the original.
This is false. It does not modify the original vector in place. That is the cause of your confusion. When the receiver is pub fn with_x(mut self, x: f32) -> Self {
self.x = x;
self
} Using your example above:
#[test]
fn vec3_copy() {
let foo = glam::Vec3::ZERO;
let modified_foo = foo
.with_x(2.0)
.with_y(3.0);
// foo has not changed
assert_eq!(0.0, foo.x);
assert_eq!(0.0, foo.y);
assert_eq!(0.0, foo.z);
// modified_foo has the new values specified by the `with_x` and `with_y` methods and the
// original value for z
assert_eq!(2.0, modified_foo.x);
assert_eq!(3.0, modified_foo.y);
assert_eq!(0.0, modified_foo.z);
} |
with_*
to set_*
& add new with_*
methods for vector typeswith_
and add new set_
method for vector types
Sorry, I didn't update the original description. The I was talking about the // modify `foo` with new values
foo
.set_x(2.0)
.set_y(3.0);
// create a copy of `foo` with new values
foo
.with_x(2.0)
.with_y(3.0); |
The fields are public. You can just do this: foo.x = 2.0;
foo.y = 3.0; |
Objective:
The current behavior of the
with_
methods for vector types is usingmut self
type, which can be confusing since it relies on theCopy
trait for implicit copy.There are also no convenient
set_
method for method chaining pattern.Solution:
with_
method of vector types to useself
and create an explicit copy instead.set_
method to allow for method chaining when mutating vector types.