-
Notifications
You must be signed in to change notification settings - Fork 53
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
feat: mention struct update syntax #37
Conversation
When talking about the `with` expression in C#, mention the struct update syntax [1] as something similar in Rust. [1]: https://doc.rust-lang.org/stable/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. The struct update syntax is something certainly worth mentioning, but I don't think it's comparable to with
. For example, if Point
is part of some module then the fields x
and y
would be private to the code that's external to the module. The Point
would then have to be defined as:
mod points {
#[derive(Debug)]
pub struct Point { pub x: i32, pub y: i32 }
}
fn main() {
use points::Point;
let pt = Point { x: 123, y: 456 };
let pt = Point { x: 789, ..pt };
println!("{pt:?}"); // prints: Point { x: 789, y: 456 }
}
to use the struct update syntax from outside the module. Also note that if you make the fields public then the whole impl
block can be skipped. Consequently, the emulation example is still valid so I would leave it intact but then add your bits about the struct update syntax with the above example. I would then point out that it's generally more common to see that use within the module that has access to private details of its types.
Yeah, I was debating whether that should be mentioned explicitly, or if it would complicate things too much. using System;
public readonly record struct Point {
internal readonly int X {get; init;}
private readonly int Y {get; init;}
public Point(int x, int y) => (X,Y)=(x,y);
public override String ToString() => $"Point {{ X = {this.X}, Y= {this.Y} }}";
}
public class Program
{
public static void Main()
{
var pt = new Point(123, 456);
pt = pt with { X = 789 }; // Error if `X` is declared private above, or if `Main()` is in another project/module.
Console.WriteLine(pt.ToString()); // prints: Point { X = 789, Y = 456 }
}
} |
Right, but in the C# example, |
Add struct update syntax as additional information, do not remove mention of explicit constructs to emulate a `with`. Also mention that fields need to be accessible to use the syntax.
Ah, yeah, fair point! Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made a few suggestions then we're good to merge. 🏁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just had a thought. Perhaps it's best to compare the struct update syntax of Rust with non-destructive mutation of non-record struct
types using with
, which has been possible since C# 10. It seems a lot more comparable. The difference is that C# does a non-destructive mutation (copy then update) whereas Rust does (partial) moves. I would suggest starting with a C# example of Point
as a struct
with public and (read-write) fields:
var pt = new Point { X = 123, Y = 456 };
Console.WriteLine(pt.ToString()); // prints: (123, 456)
pt = pt with { X = 789 };
Console.WriteLine(pt.ToString()); // prints: (789, 456)
struct Point
{
public int X;
public int Y;
public override string ToString() => $"({X}, {Y})";
}
Then go on to show the same is possible in Rust using the struct update syntax and end on the differences.
Instead of record structs, as a plain struct is more comparable to Rust's.
I updated it according to the suggestions - at least, I hope I understood them correctly ^^. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry this took so long, @fitzchivalrik, but I integrated the final edits with d655d1b and this is good to go now!
Thanks for contribution and working through the review!
@fitzchivalrik If you could agree to the CLA then I can get this merged. Thanks! |
@atifaziz No worries, thanks for coming back to it. If this causes complications, I would be open to agree to the CLA only for this specific contribution (and not in general), if this is at all possible. |
@fitzchivalrik I understand. How about this? You sign it now for this contribution and if you feel uncomfortable with the CLA at any point thereafter and want to revoke it for future contributions, you always have the option to terminate the agreement by issuing the following command:
However, I'd encourage you to seek clarity on the CLA so you're eventually comfortable with it because we appreciate and value your contributions! |
Sorry for the delay. Thanks for the terminate command - agreeing, and then terminating it later here is fine for me. |
@microsoft-github-policy-service terminate |
@fitzchivalrik please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
When talking about the
with
expression in C#,mention the struct update syntax1 as something
similar in Rust.
Footnotes
https://doc.rust-lang.org/stable/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax ↩