3 ms·
Struct literal changes while welcomed, have the issue of being a possible source of bugs, if there are overlapping fields, type Habitat struct { Burrow strin
by pjmlp 2mo ago
Struct literal changes while welcomed, have the issue of being a possible source of bugs, if there are overlapping fields,
type Habitat struct {
Burrow string
}
type Gopher struct {
Name string
Burrow string
Habitat
}
It will not initialise what one expects, here it is a contrived example, however it may not be easy to spot in more complex source code.
https://go.dev/play/p/dsY6tK5S8Ie https://go.dev/play/p/dsY6tK5S8Ie
Better generics and improved SIMD are nice additions as well.
- j3nz 2mo agoI'd say it is as expected https://go.dev/play/p/sy6SMrOiw4y https://go.dev/play/p/sy6SMrOiw4y
- pjmlp 2mo agoI would at least expect a go vet warning in such cases.
- 0x696C6961 2mo agoMhm, probably worth a golang-ci check for duplicate field names which are accessed by methods on the embedded type.
- pjmlp 2mo agoBetter would be a got vet check. I understand the need not to break existing code that might have such fields.
- 0x696C6961 2mo agoI think that's a no-go because vet checks have no-false-positive policy. Ie, when go vet flags something, its a bug.
- pjmlp 2mo agoI would say that initialising the wrong field because a dev is unaware of a clash between Gopher.Burrow and Gopher.Habitat.Burrow (naturally in more complex code), when upgrading to 1.27 and taking advantage of the feature without realising it, is a bug.
- 0x696C6961 2mo agoWell either way, these things usually land in golangci-lint first and get promoted if they're deemed useful enough.
- amiga386 2mo agoGo has had this behaviour for promoting fields (provided they don't clash) for some time, this is just extending the language feature to initialisers. Your contrived example doesn't initialise the embedded struct that also contains a "Burrow" field. If it did that at all, even without naming the Burrow field... you would not be allowed to initialise the struct, because of the ambiguity. https://go.dev/ref/spec#Composite_literals https://go.dev/ref/spec#Composite_literals > A key must not denote a promoted field inside an embedded struct if that struct is also specified by another key. > Given the declarations type Object struct { name, color string } type Point3D struct { Object; x, y, z float64 } type Line struct { Object; p, q Point3D } > .... field selectors may not denote overlapping fields: obj := Object{"edge", "black"} line3 := Line{Object: obj, name: "diagonal"} // invalid: name denotes a field inside Object
- pjmlp 2mo agoWhich error? https://go.dev/play/p/CFWVXkFBOEX https://go.dev/play/p/CFWVXkFBOEX Note that I added a name field to Line. Data: {edge black} -- {{edge black} {{ } 0 0 0} {{ } 0 0 0} diagonal} Oops now Object.name is empty, which is my point.
- amiga386 2mo ago./prog.go:20:29: cannot specify promoted field name and enclosing embedded field Object Which is what you get if you don't add a direct "name" field to Line, because it's then completely unambiguous, the deeper "name"s are not promotable.
- zimpenfish 2mo agoI've missed something - what were you expecting from that code? Would anyone expect the `Burrow` inside the `Habitat` to be initialised instead of the top-level `Burrow`?
- qwm 2mo agoFunny enough, in one of my projects I created a struct with a string field just to have a distinct type that couldn't accidentally be initialized by typing a string. This update completely messes that up lol