Re: [go-nuts] How to know if interface{} data is nil w/o reflecting?
I don't understand this comparison. The C idiom you mention is concretely typed (i.e. C doesn't have interfaces, so it doesn't have dynamic types), so I fail to see what it has to do with interfaces. And it makes *far* more sense to check if you got passed a nil-pointer, than to check the concrete value of an interface -- i.e. something like this makes of course *some* sense, in Go: func Foo(p *string) { if p != nil { *p = doSomeStuff() } } It makes sense to check p for nil, because you know its type and you know you can't use it, if its nil. It's thus a very different problem than what this thread is about. Moreover, how does, what you say what was said above? i.e. a) As a user of an interface, its dynamic value shouldn't concern you, in general, b) not all zero values are nil, so checking for nil to see whether the dynamic value is the zero value doesn't make sense and c) the zero value - including nil - is a perfectly valid implementation of an interface? On Tue, Jan 2, 2018 at 1:40 AM, David Collier-Brownwrote: > Drifting back toward the original subject, I'm reminded of the non-bsd-c > idiom of > > char *foo(char *p) { > if (p != NULL && *p != NULL) { > return some string operation... > } > ... > > It seems logical to check the type of the contents of an interface > type, and its presence in a function that can take nil types and > nil contents, much as in the C idiom. > > Mind you, I do find type assertions a bit clunky. > > --dave > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Extending an existing type by embedding
Bingo! Thanks a lot for your *clear explanation* Jason! I went with your first choice and it works perfectly. Now wish somebody can answer the second part -- extend it even further for two different `VisitToken()` behaviors... On Mon, Jan 1, 2018 at 11:39 PM, Jason Phillipswrote: > html.NewTokenizer returns a pointer to a Tokenizer. So, you probably want > to embed a pointer: > type MyTokenizer struct { > *html.Tokenizer > } > > func NewMyTokenizer(i io.Reader) *MyTokenizer { > z := html.NewTokenizer(i) > return {z} > } > > If for some reason your want/need the Tokenizer value, you'll need to > dereference it before making it part of your MyTokenizer structure: > > type MyTokenizer struct { > html.Tokenizer > } > > func NewMyTokenizer(i io.Reader) *MyTokenizer { > z := html.NewTokenizer(i) > return {*z} > } > > > Jason > > On Monday, January 1, 2018 at 11:14:14 PM UTC-5, Tong Sun wrote: >> >> >> >> On Mon, Jan 1, 2018 at 10:21 PM, Ian Lance Taylor >> wrote: >> >> On Mon, Jan 1, 2018 at 6:46 PM, Tong Sun wrote: >>> > >>> > I think I generally understand how embedding >>> > (https://golang.org/doc/effective_go.html#embedding) works in GO. >>> > However, when it comes to the following problem, I'm at lost again. >>> > >>> > I'm trying to extend the `html.Tokenizer` with new methods of my own: >>> > >>> > type MyTokenizer struct { >>> > html.Tokenizer >>> > } >>> > >>> > >>> > func NewMyTokenizer(i io.Reader) *MyTokenizer { >>> > z := html.NewTokenizer(i) >>> > return *MyTokenizer(z) >>> > return {z} >>> > } >>> > >>> > >>> > >>> > so code like >>> > >>> > z := html.NewTokenizer(body) >>> > ... >>> > func parseBody(z *html.Tokenizer) { >>> > tt := z.Next() >>> > ... >>> > testt := z.Token() >>> > ... >>> > >>> > >>> > can become: >>> > >>> > z := NewMyTokenizer(body) >>> > ... >>> > func (z *MyTokenizer) parseBody() { >>> > tt := z.Next() >>> > ... >>> > >>> > testt := z.Token() >>> > ... >>> > >>> > >>> > >>> > >>> > However, I'm really struggling to make it work as I was expected. >>> > >>> > Somebody help please, what's the proper way to extend a type with new >>> > methods of my own, while still able to access all existing methods? >>> >>> The best way to get help for this is to show us precisely what you >>> did, ideally in a small complete, stand-alone, example, >> >> >> The *small complete, stand-alone, example *has been provided in OP as >> https://github.com/suntong/lang/blob/master/lang/Go/src/xml >> /htmlParserTokens.go >> >> and tell us >>> what you expected to happen, and tell us precisely what happened >>> instead. >> >> >> *What expected to happen*: adding the following would work: >> >> type MyTokenizer struct { >> html.Tokenizer >> } >> >> >> func NewMyTokenizer(i io.Reader) *MyTokenizer { >> z := html.NewTokenizer(i) >> return *MyTokenizer(z) >> return {z} >> } >> >> >>> In this case I don't know what to suggest because you didn't >>> say what you expect and you didn't say what happened. >>> >> >> Can't make it work. The >> >> return *MyTokenizer(z) >> return {z} >> >> Are just the last two attempts that I make, apart from many other failed >> attempts that I've lost track of, but *neither compiles*. >> >> > Further more, how to extend the above even further? -- >>> > >>> > - I plan to define an interface with a new method `WalkBody()`, in >>> which a >>> > "virtual" method of `VisitToken()` is used. >>> > - Then I plan to define two different type of MyTokenizer, with their >>> own >>> > `VisitToken()` methods, so the same `WalkBody()` method defined in >>> > MyTokenizer will behave differently for those two different types. >>> > >>> > How to architect above in Go? >>> >>> First, think in Go terms, don't think in terms like "virtual method" >>> that do not exist in Go. >>> >>> What you want is something like >>> >>> type TokenVisitor interface { >>> VisitToken() >>> } >>> >>> Then your WalkBody function will take a TokenVisitor, and your >>> different types will implement different VisitToken methods. >>> >>> (I see that you said WalkBody method, but you probably want a WalkBody >>> function instead.) >>> >> >> I did meant WalkBody method. See: >> >> https://github.com/suntong/lang/blob/master/lang/Go/src/xml/ >> htmlParserTokens.go#L54 >> >> -- > You received this message because you are subscribed to a topic in the > Google Groups "golang-nuts" group. > To unsubscribe from this topic, visit https://groups.google.com/d/ > topic/golang-nuts/FRE_A6cNzW8/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options,
Re: [go-nuts] Extending an existing type by embedding
html.NewTokenizer returns a pointer to a Tokenizer. So, you probably want to embed a pointer: type MyTokenizer struct { *html.Tokenizer } func NewMyTokenizer(i io.Reader) *MyTokenizer { z := html.NewTokenizer(i) return {z} } If for some reason your want/need the Tokenizer value, you'll need to dereference it before making it part of your MyTokenizer structure: type MyTokenizer struct { html.Tokenizer } func NewMyTokenizer(i io.Reader) *MyTokenizer { z := html.NewTokenizer(i) return {*z} } Jason On Monday, January 1, 2018 at 11:14:14 PM UTC-5, Tong Sun wrote: > > > > On Mon, Jan 1, 2018 at 10:21 PM, Ian Lance Taylor> wrote: > >> On Mon, Jan 1, 2018 at 6:46 PM, Tong Sun > > wrote: >> > >> > I think I generally understand how embedding >> > (https://golang.org/doc/effective_go.html#embedding) works in GO. >> > However, when it comes to the following problem, I'm at lost again. >> > >> > I'm trying to extend the `html.Tokenizer` with new methods of my own: >> > >> > type MyTokenizer struct { >> > html.Tokenizer >> > } >> > >> > >> > func NewMyTokenizer(i io.Reader) *MyTokenizer { >> > z := html.NewTokenizer(i) >> > return *MyTokenizer(z) >> > return {z} >> > } >> > >> > >> > >> > so code like >> > >> > z := html.NewTokenizer(body) >> > ... >> > func parseBody(z *html.Tokenizer) { >> > tt := z.Next() >> > ... >> > testt := z.Token() >> > ... >> > >> > >> > can become: >> > >> > z := NewMyTokenizer(body) >> > ... >> > func (z *MyTokenizer) parseBody() { >> > tt := z.Next() >> > ... >> > >> > testt := z.Token() >> > ... >> > >> > >> > >> > >> > However, I'm really struggling to make it work as I was expected. >> > >> > Somebody help please, what's the proper way to extend a type with new >> > methods of my own, while still able to access all existing methods? >> >> The best way to get help for this is to show us precisely what you >> did, ideally in a small complete, stand-alone, example, > > > The *small complete, stand-alone, example *has been provided in OP as > > https://github.com/suntong/lang/blob/master/lang/Go/src/xml/htmlParserTokens.go > > and tell us >> what you expected to happen, and tell us precisely what happened >> instead. > > > *What expected to happen*: adding the following would work: > > type MyTokenizer struct { > html.Tokenizer > } > > > func NewMyTokenizer(i io.Reader) *MyTokenizer { > z := html.NewTokenizer(i) > return *MyTokenizer(z) > return {z} > } > > >> In this case I don't know what to suggest because you didn't >> say what you expect and you didn't say what happened. >> > > Can't make it work. The > > return *MyTokenizer(z) > return {z} > > Are just the last two attempts that I make, apart from many other failed > attempts that I've lost track of, but *neither compiles*. > > > Further more, how to extend the above even further? -- >> > >> > - I plan to define an interface with a new method `WalkBody()`, in >> which a >> > "virtual" method of `VisitToken()` is used. >> > - Then I plan to define two different type of MyTokenizer, with their >> own >> > `VisitToken()` methods, so the same `WalkBody()` method defined in >> > MyTokenizer will behave differently for those two different types. >> > >> > How to architect above in Go? >> >> First, think in Go terms, don't think in terms like "virtual method" >> that do not exist in Go. >> >> What you want is something like >> >> type TokenVisitor interface { >> VisitToken() >> } >> >> Then your WalkBody function will take a TokenVisitor, and your >> different types will implement different VisitToken methods. >> >> (I see that you said WalkBody method, but you probably want a WalkBody >> function instead.) >> > > I did meant WalkBody method. See: > > > https://github.com/suntong/lang/blob/master/lang/Go/src/xml/htmlParserTokens.go#L54 > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Extending an existing type by embedding
On Mon, Jan 1, 2018 at 10:21 PM, Ian Lance Taylorwrote: > On Mon, Jan 1, 2018 at 6:46 PM, Tong Sun wrote: > > > > I think I generally understand how embedding > > (https://golang.org/doc/effective_go.html#embedding) works in GO. > > However, when it comes to the following problem, I'm at lost again. > > > > I'm trying to extend the `html.Tokenizer` with new methods of my own: > > > > type MyTokenizer struct { > > html.Tokenizer > > } > > > > > > func NewMyTokenizer(i io.Reader) *MyTokenizer { > > z := html.NewTokenizer(i) > > return *MyTokenizer(z) > > return {z} > > } > > > > > > > > so code like > > > > z := html.NewTokenizer(body) > > ... > > func parseBody(z *html.Tokenizer) { > > tt := z.Next() > > ... > > testt := z.Token() > > ... > > > > > > can become: > > > > z := NewMyTokenizer(body) > > ... > > func (z *MyTokenizer) parseBody() { > > tt := z.Next() > > ... > > > > testt := z.Token() > > ... > > > > > > > > > > However, I'm really struggling to make it work as I was expected. > > > > Somebody help please, what's the proper way to extend a type with new > > methods of my own, while still able to access all existing methods? > > The best way to get help for this is to show us precisely what you > did, ideally in a small complete, stand-alone, example, The *small complete, stand-alone, example *has been provided in OP as https://github.com/suntong/lang/blob/master/lang/Go/src/xml/htmlParserTokens.go and tell us > what you expected to happen, and tell us precisely what happened > instead. *What expected to happen*: adding the following would work: type MyTokenizer struct { html.Tokenizer } func NewMyTokenizer(i io.Reader) *MyTokenizer { z := html.NewTokenizer(i) return *MyTokenizer(z) return {z} } > In this case I don't know what to suggest because you didn't > say what you expect and you didn't say what happened. > Can't make it work. The return *MyTokenizer(z) return {z} Are just the last two attempts that I make, apart from many other failed attempts that I've lost track of, but *neither compiles*. > Further more, how to extend the above even further? -- > > > > - I plan to define an interface with a new method `WalkBody()`, in which > a > > "virtual" method of `VisitToken()` is used. > > - Then I plan to define two different type of MyTokenizer, with their own > > `VisitToken()` methods, so the same `WalkBody()` method defined in > > MyTokenizer will behave differently for those two different types. > > > > How to architect above in Go? > > First, think in Go terms, don't think in terms like "virtual method" > that do not exist in Go. > > What you want is something like > > type TokenVisitor interface { > VisitToken() > } > > Then your WalkBody function will take a TokenVisitor, and your > different types will implement different VisitToken methods. > > (I see that you said WalkBody method, but you probably want a WalkBody > function instead.) > I did meant WalkBody method. See: https://github.com/suntong/lang/blob/master/lang/Go/src/xml/htmlParserTokens.go#L54 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Extending an existing type by embedding
On Mon, Jan 1, 2018 at 6:46 PM, Tong Sunwrote: > > I think I generally understand how embedding > (https://golang.org/doc/effective_go.html#embedding) works in GO. > However, when it comes to the following problem, I'm at lost again. > > I'm trying to extend the `html.Tokenizer` with new methods of my own: > > type MyTokenizer struct { > html.Tokenizer > } > > > func NewMyTokenizer(i io.Reader) *MyTokenizer { > z := html.NewTokenizer(i) > return *MyTokenizer(z) > return {z} > } > > > > so code like > > z := html.NewTokenizer(body) > ... > func parseBody(z *html.Tokenizer) { > tt := z.Next() > ... > testt := z.Token() > ... > > > can become: > > z := NewMyTokenizer(body) > ... > func (z *MyTokenizer) parseBody() { > tt := z.Next() > ... > > testt := z.Token() > ... > > > > > However, I'm really struggling to make it work as I was expected. > > Somebody help please, what's the proper way to extend a type with new > methods of my own, while still able to access all existing methods? The best way to get help for this is to show us precisely what you did, ideally in a small complete, stand-alone, example, and tell us what you expected to happen, and tell us precisely what happened instead. In this case I don't know what to suggest because you didn't say what you expect and you didn't say what happened. > Further more, how to extend the above even further? -- > > - I plan to define an interface with a new method `WalkBody()`, in which a > "virtual" method of `VisitToken()` is used. > - Then I plan to define two different type of MyTokenizer, with their own > `VisitToken()` methods, so the same `WalkBody()` method defined in > MyTokenizer will behave differently for those two different types. > > How to architect above in Go? First, think in Go terms, don't think in terms like "virtual method" that do not exist in Go. What you want is something like type TokenVisitor interface { VisitToken() } Then your WalkBody function will take a TokenVisitor, and your different types will implement different VisitToken methods. (I see that you said WalkBody method, but you probably want a WalkBody function instead.) Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] Extending an existing type by embedding
Hi, I think I generally understand how embedding (https://golang.org/doc/effective_go.html#embedding) works in GO. However, when it comes to the following problem, I'm at lost again. I'm trying to extend the `html.Tokenizer` with new methods of my own: type MyTokenizer struct { html.Tokenizer } func NewMyTokenizer(i io.Reader) *MyTokenizer { z := html.NewTokenizer(i) return *MyTokenizer(z) return {z} } so code like z := html.NewTokenizer(body) ... func parseBody(z *html.Tokenizer) { tt := z.Next() ... testt := z.Token() ... can become: z := NewMyTokenizer(body) ... func (z *MyTokenizer) parseBody() { tt := z.Next() ... testt := z.Token() ... However, I'm really struggling to make it work as I was expected. Somebody help please, what's the proper way to extend a type with new methods of my own, while still able to access all existing methods? Further more, how to extend the above even further? -- - I plan to define an interface with a new method `WalkBody()`, in which a "virtual" method of `VisitToken()` is used. - Then I plan to define two different type of MyTokenizer, with their own `VisitToken()` methods, so the same `WalkBody()` method defined in MyTokenizer will behave differently for those two different types. How to architect above in Go? For your convenience, you can use this as an easy start, when demonstrating your architectural solution. https://github.com/suntong/lang/blob/master/lang/Go/src/xml/htmlParserTokens.go Thx a lot! -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] How to know if interface{} data is nil w/o reflecting?
Drifting back toward the original subject, I'm reminded of the non-bsd-c idiom of char *foo(char *p) { if (p != NULL && *p != NULL) { return some string operation... } ... It seems logical to check the type of the contents of an interface type, and its presence in a function that can take nil types and nil contents, much as in the C idiom. Mind you, I do find type assertions a bit clunky. --dave -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Fuzzy behaviour of go test with examples in sort package
On Mon, Jan 1, 2018 at 8:37 PM Kshitij Saraogiwrote: > While running the test suite in the "sort" pacakge, I found that all the examples are not being evaluated. > I tried running `$ go test -v src/sort` from the base directory of the repository. > > The tests such as `ExampleIntsAreSorted`, `ExampleFloat64s` are not run unless explicitly instructed to. > I made changes to the expected "Output" in each of these examples to a wrong value. > Surprisingly, the test suite still passed. Is there a reason why this happening? > > Also, I think this is the reason why these examples are not displayed in the "godoc" of the sort package. > How can we fix this? To test a package with import path foo one either passes nothing to go test when in the $GOPATH/src/foo directory or, from any directory, passes foo as the argument. Passing src/sort will not the the stdlib sort package. With Go 1.10 beta 1: ~> go version go version devel +9ce6b5c2ed Thu Dec 7 17:38:51 2017 + linux/amd64 ~> go test -v sort | grep ExampleIntsAreSorted === RUN ExampleIntsAreSorted --- PASS: ExampleIntsAreSorted (0.00s) ~> -- -j -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] Fuzzy behaviour of go test with examples in sort package
While running the test suite in the "sort" pacakge, I found that all the examples are not being evaluated. I tried running `$ go test -v src/sort` from the base directory of the repository. The tests such as `ExampleIntsAreSorted`, `ExampleFloat64s` are not run unless explicitly instructed to. I made changes to the expected "Output" in each of these examples to a wrong value. Surprisingly, the test suite still passed. Is there a reason why this happening? Also, I think this is the reason why these examples are not displayed in the "godoc" of the sort package. How can we fix this? -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] How to know if interface{} data is nil w/o reflecting?
Since an interface can be nil I’ve been assuming interface behaves like slice with a pointer to the concrete data within a reference struct (that also includes the data type) which is passed around as an interface var. This playground shows that the interface var is a similar reference type to slice: https://play.golang.org/p/PIWpyrpwNq5 I didn’t know where to look in the Go source to find the definition of an interface (src/runtime/type.go, src/runtime/iface.go, src/go/types/type.go, and src/cmd/compile/internal/types/type.go weren't immediately clear to me). The specification says an interface stores a value; my misunderstanding is that while the interface var may refer to data elsewhere, this data is a copy of the original. So using a pointer assigned to an interface as a way to save stack space is absurd, but using a pointer assigned to an interface as a way to modify the original data does make sense. Arguing about nil interface vs nil pointer in an interface is not absurd, I apologize for my statement. Matt On Saturday, December 30, 2017 at 1:22:37 PM UTC-6, Matt Harden wrote: > > I don't know what you mean by "reference type" - as I understand it, > that's not a meaningful phrase in Go. Did you mean "interface"? If so, we > store pointers in interfaces all the time in Go. When we set an interface > variable i to x, we are semantically making a copy of x and storing it in > i. We won't be able to modify x using i (because it has a copy of x, not a > pointer to the original). If x is a pointer to something, then we *will* be > able to modify that something using i. > > On Sat, Dec 30, 2017 at 8:08 AMwrote: > >> Storing a pointer in a reference type seems absurd to me. >> >> Matt >> >> >> On Friday, December 29, 2017 at 11:07:31 PM UTC-6, Matt Harden wrote: >> >>> I really wish Go had not chosen to propagate Hoare's billion-dollar >>> mistake. I do realize it's all tied up with the idea that initialization is >>> cheap and zero values should be useful when possible, and therefore >>> pointers, interfaces, channels, etc. need zero values. >>> >>> I wonder how different Go would have been if we had required all >>> pointers and interfaces (only) to be initialized, and made the zero value >>> for maps a writable empty map. In cases where nil pointers and interfaces >>> are useful, it seems to me that sentinel values would serve the purpose >>> equally well. For example, comparing errors with (ok) would be (one >>> character) shorter, more meaningful and less confusing than comparing with >>> nil, which can be so confusing for newcomers that we have an FAQ for it. >>> Few would be surprised to find (e != ok) when (e == (*myerror)(nil)) -- and >>> if there were no nil pointers, it wouldn't even be a valid question to ask. >>> We could still use pointers as stand-ins for Optional types, just with >>> sentinel values like sql.NullInt64 to serve the purpose nil does. >>> >>> I know this is likely a non-starter for Go2, for good reasons - >>> virtually all Go code would need significant, probably manual refactoring, >>> and interoperability with other languages would suffer, to name two that >>> come to mind. >>> >>> I think what I really want is Haskell plus all the benefits Go has >>> relative to it, including Go's incredibly simple language spec, standard >>> library, short compile times, etc. Is that too much to ask? :-) >>> >>> On Fri, Nov 3, 2017 at 9:30 AM wrote: >>> >> This thread helped me to understand better the current scenario and the implications of a future change. I would be glad to recognize if this conversation had changed my mind, but it didn't. Some programmers discovered that they could use this "valid nil interface" to do some smart tricks, as Jakob kindly has shown. While I do recognize that was indeed smart, Jakob offered another easy way of attaining the desired effect for his constructor. It would be pretty easy if he had to code that way to begin with. I consider unfortunate the fact that I can't safely use an interface where previously I used a pointer. To me, at least, that is a natural evolutionary path for a piece of software as soon as the developer discover opportunities to leverage the commonality of an interface. I think such possibility would be more broadly useful than what we can do now. Go has a bunch of interesting tricks and useful idioms, but this trick is proving costly. Thanks to everyone. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. >>> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com. >>> >>> For more options, visit https://groups.google.com/d/optout. >>> -- >> You received this message because you are