![]() Modify how the default values are populated for the ExampleStruct() constructor.Īlso, I am aware that I could use a field like this instead of my Value property: public readonly int Value īut my philosophy is to use fields privately unless they are const or static. Call the ExampleStruct(int value = 1) constructor. So, as it stands right now, the default constructor actually created an object that is invalid in the context I need it for. Throw new ArgumentException("Value is out of range") Add this to the ExampleStruct(int value = 1) constructor above: if(value 3) To make matters worse, my actual code is checking to see that int value = 1 parameter is within a valid range within the constructor. Since it does that, it uses int's default value of 0 as Value. So, like how I'm calling this() my explicit constructor, in Main, that same thing occurs where new ExampleStruct() is actually calling ExampleStruct() but not calling ExampleStruct(int value = 1). The reason is that all structs have public parameter-less constructors. This code outputs 0 and does not output 1. The problem is when I try to use this constructor without specifying a value and desiring to use the defaulted value of 1 for the parameter: private static void Main(string args)ĮxampleStruct example1 = new ExampleStruct() Here is an example: public struct ExampleStruct It all came down like this.Ī Config struct was initialized with field:value syntax, and I added a new attribute without a possible "sensible default.I ran into this issue today when creating a struct to hold a bunch of data. Last month I created a bug due to a missing constructor. Public Structs and Libraries are even more sensitive to changes. Reason 3 - Exported Structs and Public Libraries Point being? It would be best if you optimized for flexibility and refactoring as a team in your project. I don't know about you, but the latest commit in my project was like 3h ago, lol. The last commit to Mutex source was in November 2019. Reason 2 - Your code changes weekly, RWMutex doesn't A wrong default value was supplied as the Go compiler can't pick it up given from a compiler perspective, the value is not missing it thinks you didn't pass it because you wanted the compiler to use a default value. However, I can link to 3 PRs in the last 6 months that caused a production bug because of a missing dedicated constructor. I have been writing Go for 4 years, and I can't pinpoint a single struct I designed using default values solely. ReaderWait int32 // number of departing readers ![]() ReaderCount int32 // number of pending readers ReaderSem uint32 // semaphore for readers to wait for completing writers WriterSem uint32 // semaphore for writers to wait for completing readers W Mutex // held if there are pending writers To be objective, one struct has default values that work like a charm, and I frequently use: sync.RWMutex. ![]() I needed to change only one place.Įvery struct deserves its constructor! Your future self will thank you during the next refactoring session :) I encapsulated this responsibility into a single function. What's your experience? Agree or do you think differently?įortunately, I can avoid all that mess, and a large PR for my teammates, because I have control over the struct creation. Generally, I don't see any value in the field:value constructors given any good IDE will graphically show you the names like my previous screenshot. Don't even try to fix it with an optional setter. MaxGasPrice will accidentally be 0 by default, turning the struct into an invalid state. However, if I would label the constructor elements "explicitly as field:value pairs, the initializers can appear in any order, with the missing ones left as their respective zero values", the refactoring could quickly end up with a production bug, as the compiler wouldn't point out all the places I forgot to pass a new value so that's even worse approach. That's a very realistic estimate as I have already been in several such situations on various projects. If I had to add another attribute to the Tx struct, MaxGasPrice, I would have to modify tens/hundreds of files (depending on the codebase size/implementation). Let's say I don't create a dedicated constructor NewBaseTx(). Reason 1 - Sensible default values are rare No constructor Let me walk you through my four reasons for doing this. Func NewBaseTx(from, to common.Address, value uint, nonce uint, data string) Tx
0 Comments
Leave a Reply. |