Greetings you all,
I am new to rust and decided to prompt chatgpt to test me having learnt from the first chapter of the rust book down to the Struct part.
Here was the test
Define a struct called Rectangle with fields width and height.
Implement a method inside the Rectangle struct that returns the area of the rectangle. The method should return an Option—return None if either width or height is zero, as a rectangle with zero dimensions is invalid.
Then, implement a method to compare two rectangles:
If the first rectangle is larger, return Some("First").
If the second rectangle is larger, return Some("Second").
If they are the same size, return Some("Equal").
If one of the rectangles is invalid, return None.
I made a struct.rs file for my struct and this was my logic
use structs::Rectangle;
mod structs;
fn main(){
let rec1 = structs::Rectangle{
width: 55,
height: 46
};
match rec1.area(){
Some(a) => println!("The area is {}",a),
None => panic!("Sorry error")
}
let rec2: Rectangle = structs::Rectangle{
..rec1
};
println!("Rec1 is {:?} to Rec2", rec1.compare(rec2));
}
Haven submitted to chatgpt for check, it brought to my notice a couple issues of which i have studied about but i still need your idea or contribution on this particular part where it said i can't directly compare the Option values using operators.... and the second part where it says i shouldn't compare self.width.to_string() with "0" i literally cracked my brain for an alternative while attempting the question but i found none because 0 itself is an i32 type and self.width is a &u32 type... i tried using into() and deferencing the &u32 but it wouldn't work:(
I will definitely check the playground out and yeah i make use rustlings too I've solved all exercises down to structs and trying to learn enums to proceed.
If you think about it a bit more, it can't be true can it? Are signed 32 bits the only numeric type allowed to have values of 0? It would be ludicrous if they were.
What you've spotted is that with no other context, rust infers that a 0 is type i32. It's an arbitrary default numeric type.
But
let a: u8 = 0;
let b: i64 = 0;
let c: usize = 0;
Is all fine.
In fact:
fn needs_u8(n: u8) {
// ...
}
let a = 0;
needs_u8(a); // a is inferred to be a u8
Rectangles with a size of zero in either dimension are, usually, perfectly valid. But...
If you really want to maintain that invariant, then make the fields private. Then you can return a failure once, in initialization, rather than many times all over. In fact, you could even use NonZeroU32 (don't worry about it though). In any case, please don't pretend that certain values are acceptable, only to throw errors down the line (again, that's GPT's fault, not yours).
Rust specifically has an enum, std::cmp::Ordering, for the result of a comparison. Use the Greater, Lesser, and Equal variants, rather than "First", "Second", and "Equal". If you've addressed my first two points, you can also drop the Option part entirely.
These are issues with ChatGPT's challenge, not your implementation. However, I think it's indicative of how bad LLMs are at Rust: in the future, I'd recommend avoiding them.
That Ord impl claims Rect::new(55, 46) is equal to Rect::new(46, 55). This has some implications such as the inability to store these two rectangles in a BTreeSet.
Relatedly, the PartialOrd impl violates the requirement:
a == b if and only if partial_cmp(a, b) == Some(Equal).
The second assertion fails:
let rec1 = Rectangle::new(55, 46);
let rec2 = Rectangle::new(46, 55);
assert_eq!(rec1.partial_cmp(&rec2), Some(Ordering::Equal));
assert_eq!(rec1, rec2);
There are a couple of ways to order by area that don’t run into this problem:
Only implement PartialOrd such that rectangles with the same area and differing dimensions are both unequal and unorderable.
Sort by area first, and then break ties by ordering on something else that distinguishes rectangle of equal area. The most obvious choice would be either width or height, but you could also do something more complicated like sorting by aspect ratio instead.