type MyStorage struct {
path string
max_retry int
op *Operation
}
It would be nice if I can write in this way instead:
type MyStorage struct {
Path_info string = '/my/default/path'
Max_retry int = 3
Op *Operation
}
In struct construction, I then only need to provide the Operation
object and the rest would be initialized to default as s := MyStorage
{op: new(Operation)}
If field values are provided during construction time, then the
default values will be overridden. Such as
s := MyStorage{path_info: '/foo', max_retry: 10, op: new(Operation)}
The compiler does not need to alloc storage during the type definition
even if default value is provided, it only needs to remember them and
later, if no values provided, allocate the memory and store the
defaults.
It will not only save tedious typing time if one constructs a lot
objects with most fields apply only defaults and just some needs to be
overridden but also helps code refactoring in the future (no changes
to the object initialization code if fields added have default values
and only those that those fields need to be initialized to different
values)
I'd like to see others opinions.
Thanks.
> I am not sure if this has been discussed before but the general idea
> is that in struct definition, the language should support specifying
> default values for fields.
You can get a similar effect by writing a function which sets the
fields to the defaults. Also, in general the language encourages
thinking of the zero value as the uninitialized value. This feature
would be occasionally handy but I'm not sure it buys us much.
Ian
You can get a similar effect by writing a function which sets thefields to the defaults. Also, in general the language encourages
thinking of the zero value as the uninitialized value. This feature
would be occasionally handy but I'm not sure it buys us much.
because that gets rid of the "simplifying" part of the simplifying assumption.
defining the zero value to be non-zeroed memory would require
introducing per-field initializations that do not happen right now.
right now, zeroed memory is ready to use right away without any work.
you are proposing to change code that does not exist.
russ
> Just to expand what Ian said, the zero value as the default is
> a simplifying assumption, in the best sense. It is occasionally
> inconvenient but in exchange completely avoids discussion of
> constructors, recursive constructors, partially constructed objects, etc.
> The zero value is one of my favorite small features in Go.
It may simplify the language specification but it definitely does not
simplify using the language. Depending on implementation details the
default value of some type may be valid or not, and this decision
cannot be easily changed. This is one of the worst Go misfeatures.
--
Marcin Kowalczyk
Can you provide an example of this?
It would seem that a zero default value (as in Go) is more useful than
an undefined default value (as in C). If you require some other
initial state, isn't it prudent to set that state explicitly? (Rather
than extending the language to support arbitrary default values.) Or
am I misunderstanding the nature of your grievance?
Andrew
Anyway, as you demonstrated, your proposal doesn't completely cover
the need you described. Maybe a better approach would be coming up
with a way that simplifies flexible construction rather than tackling
default initialization. Reflection doesn't exactly make for the
prettiest code...
>> It may simplify the language specification but it definitely does not
>> simplify using the language. Depending on implementation details the
>> default value of some type may be valid or not, and this decision
>> cannot be easily changed. This is one of the worst Go misfeatures.
>
> Can you provide an example of this?
Any object containing a map.
If it didn't contain a map before and its clients relied on zero
initialization, and now it does contain a map, then every method must
face the possibility that the map has not been initialized yet. It is
impossible to ensure that any instance of that type contains an
initialized map and still allowing clients to embed it in other
objects by value.
> It would seem that a zero default value (as in Go) is more useful than
> an undefined default value (as in C).
I'm not defending the C semantics.
> If you require some other
> initial state, isn't it prudent to set that state explicitly?
If it's other than the default, then it should be stated explicitly.
But the default should not be limited to all-fields-zero; the type
should decide how to make a default instance if a default instance for
it makes sense at all.
--
Marcin Kowalczyk
> Why can't you just use a constructor "func NewT() *T {...}"?
Mutex doesn't. I want a type which is as convenient to use as Mutex,
but without constraining the implementation to have all-fields-zero as
a valid and default value.
--
Marcin Kowalczyk
m := new(Mutex)
or
var m Mutex
is easier than:
m := NewMutex()
?
yes, very much. because you can put a mutex in another
data structure and not worry about creating it separately.
having used other libraries with this property and then
had to move to C pthreads, i can attest that this is a huge
usability win. that's why Effective Go encourages making
the zero value a useful, ready to use value, no initializer
required. it's the major benefit of the simplifying assumption.
russ
The zero default initialization value often gets one trouble. The
problem I
ran into was a function call, where the function variable was only
default
initialized: and it terminated the program. I think what is proposed
is a
useful feature.
>> The zero value is one of my favorite small features in Go.
Yes, its useful in general, but it can get us into trouble. Using
typenames as variables, accidental use of :=, default intialization of
maps/functions etc... my list is growing. One day, I'll send the "Go
traps and pitfalls" list to this mailing list.
-Ganesh
>
> On Jan 12, 8:09 pm, Ian Lance Taylor <i...@google.com> wrote:
>> i3dmaster <i3dmas...@gmail.com> writes:
>>> I am not sure if this has been discussed before but the general idea
>>> is that in struct definition, the language should support specifying
>>> default values for fields.
>>
>> You can get a similar effect by writing a function which sets the
>> fields to the defaults. Also, in general the language encourages
>> thinking of the zero value as the uninitialized value. This feature
>> would be occasionally handy but I'm not sure it buys us much.
>
> The zero default initialization value often gets one trouble. The
> problem I
> ran into was a function call, where the function variable was only
> default
> initialized: and it terminated the program. I think what is proposed
> is a
> useful feature.
Every reasonable feature is useful. That is not a sufficient criterion for inclusion. The question is whether the feature is useful enough to offset the cost it adds in complexity of specification, complexity of implementation, and overwhelmingly most important, the complexity of interaction with the existing features.
On the last point, this one is a loss. It interacts badly. The existing notion of a zero value carries a lot of weight for its simplicity and you propose to break that. Not a good plan.
-rob
-shane
-rob
The exact complexity is that where now the initialization is (in C)
memset(p, 0, sizeof *p)
the proposal would require significantly more code, generated on
a per-type basis. It's doable - everything is doable - but it
complicates what is now utterly trivial code that works very well
most of the time. One need only look to the many many pages
of rules that govern C++ initializers to see how utterly non-trivial
things can get once you start introducing implicit object
initialization.
Russ
Note that in the Python version bar and baz appear *three times*, and
self is in every line, that is a lot of stuttering specially if you
have quite a few members. Go on the other hand is concise and there is
no redundant information (there is actually more information than in
the python version because it gives you the types of each element and
how they are structured in memory)
On Saturday, 26 May 2012 02:28:45 UTC+2, Ian Schumacher wrote:Sure, but for anything complicated that's not possible. For example any stuct that has a chan, slice, or map in it ...I guess you 'could' check the value inside any method that uses it and then initialize it there, but that seems kind-of messy I think.
You will find that nil slices and maps behave pretty much the way you want them to, unless you need to fill them up before using.
I know this is an old thread, but I wanted to add my 2 cents anyways.For a modern language, not having some standard initialization mechanism seems kinda crazy.
Right now it is being left up to developers to come up with their own adhoc initialization approach, i.e. a NewT() factory method, an init() method or just leave it up to the user of the code to fill in the struct fields manually ... and so on. Documentation is then left to fill that gap to explain how an object should be initialized. Adhoc approaches for common tasks == bad.
Obviously the go team ran into this problem themselves and thus had to come up with the somewhat inelegant 'make' solution.
It should be clear that developers using the language will have the same problem. Maybe there could be a mechanism to allow make to receive user defined types as well (as an example of one solution)?
Go has garbage collection, but no 'object' initialization mechanism because that's too hard ... tell me that's not crazy.
Btw, what's the main reason for maps not having a usable zero-value?
Btw, what's the main reason for maps not having a usable zero-value?
type ExampleBasic struct { Foo bool `default:"true"` //<-- StructTag with a default key Bar string `default:"33"` Qux int8 }