How to distingish between package name and object name in golang - function

package main
import (
......
"fmt"
......
)
func main() {
......
xxx:=new(xxx)
fmt.Println("1")
......
xxx.Println()//confusing
}
type xxx struct{
one int
two string
}
func (yyy *xxx) Println(){
fmt.Println("2")
yyy.Print(3)//confusing too
}
func (this *xxx) Print(a int){
fmt.Println(a)
}
This question is hunted me,what is the fastest way to tell whether it is a package name or an object name,as the code presented above,in the main func,fmt is known as a package name,because everybody knows.But when comes to xxx.Println(),how would you know whether it's a package name or an object name,assuming that the main function contains many lines of code,and it is hard to pin point the declaration of object "xxx",and,there are many packages imported and it is hard for you to search for every line of import() to see if "xxx" is listed in the packages,how do you tell what xxx is?
Same as func Println,you just come straight forward to yyy.Print(3),the receiver in the func declaration is hard to find because it is out of the screen,how would you tell what yyy is the fastest way,yyy could be either the package name and the receiver name.
If there is no such an easier way,does that mean I should always search for the import() listed packages first,and scroll the screen to the very beginning of the func declaration to find what is the receiver name,and then I can know what it is?That sounds to take too much time!

For the second question (yyy.Println() inside method Println()), I think it’s standard Go style to name your receivers with very short names. So, standard Go style would suggest:
func (x *xxx) Println() {
fmt.Println(2)
x.Print(3)
}
As for the first question… I’m not sure if you’re talking about your code, or somebody else’s code. I would say it’s pretty standard that you eventually learn about what modules a given program or library is using. (Really short variable names, and then camelCase variable names also help.)

Using short-term memory, quickly scan the source code for salient features.
package main
import (
// ......
"fmt"
// ......
)
type xxx struct {
one int
two string
}
func (this *xxx) Print(a int) {
fmt.Println(a)
}
func (yyy *xxx) Println() {
fmt.Println("2")
yyy.Print(3) // yyy is receiver *xxx
}
func main() {
// ......
xxx := new(xxx)
fmt.Println("1")
// ......
xxx.Println() // xxx is var xxx
}
Apply the language rules. For example, block and scope rules.
With practice, it's easy.
References:
The Go Programming Language Specification
Import declarations
Qualified identifiers
Selectors
Blocks
Declarations and scope

Related

Go chained function calls?

Not sure what the correct name is, but I'm looking for more information about "chained function calls" in Go. For example:
foo.DoSomething().WithThisOptionalThing()
So I can use foo.DoSomething() but with the possibility to add .WithThisOptionalThing() which does something extra's. Is this possible? Please point me in the right direction / provide some examples.
Basically, you make all your configuration functions keep returning the main "object" while you chain things together and have a final "Go" function or whatever you want to call it to make it perform the action.
Here's an example on play
package main
import (
"fmt"
)
func main() {
DoSomething().Go()
DoSomething().WithThisOptionalThing().Go()
}
type Chainable struct {
thing bool
}
func DoSomething() *Chainable {
return &Chainable{}
}
func (c *Chainable) WithThisOptionalThing() *Chainable {
c.thing = true
return c
}
func (c *Chainable) Go() error {
// Actually do something now that it's been configured
fmt.Println("Thing is", c.thing)
return nil
}
You just need to know: When it comes to chaining things your methods should either always
receive pointers and return pointers
or
receive values and return values
or
receive values and return pointers
at least they're the working combinations known to me. I couldn't find any documentation on this. If you know what's going on please let me know.

Overloading a function in go doesn't work

I have a function which currently doesn't receive a bool parameter, but then calls another function with a hardcoded bool. We need to remove the hardcoded call and allow a bool to be passed.
I first thought I could try some default parameter - my google searches resulted in that Go apparently doesn't support optional (resp. default) parameter.
So I thought I'd try function overloading.
I found this thread on reddit, which says that it works with a special directive since version 1.7.3:
https://www.reddit.com/r/golang/comments/5c57kg/when_did_function_overloading_get_slipped_in/
I am using 1.8, and still I couldn't get it to work.
I am not even sure I may be allowed to use that directive, but I was speculating that changing the function signature right away may be dangerous as I don't know who uses the function...
Anyway - even with //+overloaded it didn't work
Is there any "idiosyncratic" way or pattern to solve this problem in Go?
//some comment
//+overloaded
func (self *RemoteSystem) Apply(rpath, lpath string, dynamic bool) error {
result, err := anotherFunc(rpath, dynamic)
}
//some comment
//+overloaded
func (self *RemoteSystem) Apply(rpath, lpath string ) error {
//in this function anotherFunc was being called, and dynamic is hardcoded to true
//result, err := anotherFunc(rpath, true)
return self.Apply(rpath, lpath, true)
}
When I run my test, I get (forgive me for omitting part of the real path to file):
too many arguments in call to self.Apply
have (string, string, bool)
want (string, string)
../remotesystem.go:178: (*RemoteSystem).Apply redeclared in this block
previous declaration at ../remotesystem.go:185
Overloading isn't available in Go. Instead of writing functions with the same name that do different things, it is preferable to be more expressive with what the function does in the function name. In this instance, what would commonly be done is something like this:
func (self *RemoteSystem) Apply(rpath, lpath string, dynamic bool) error {
result, err := anotherFunc(rpath, dynamic)
}
func (self *RemoteSystem) ApplyDynamic(rpath, lpath string ) error {
//in this function anotherFunc was being called, and dynamic is hardcoded to true
return self.Apply(rpath, lpath, true)
}
Just by the name of the function, you can easily tell what is different and why.
Another example to provide some context (pun intended).
I write a lot of Google App Engine code in Go using go-endpoints. The way to log things is different depending on if you have a context or not. My logging functions ended up like this.
func LogViaContext(c context.Context, m string, v ...interface{}) {
if c != nil {
appenginelog.Debugf(c, m, v...)
}
}
func LogViaRequest(r *http.Request, m string, v ...interface{}) {
if r != nil {
c := appengine.NewContext(r)
LogViaContext(c, m, v...)
}
}
From the Reddit post:
Unicode. I can tell by the pixels.
Go doesn't support function overloading. But it does support using Unicode characters in function names, which allows you to write function names that look like other function names.
The first one is setValue, the second one is setV\u0430lue aka setV\xd0\xb0lue (with CYRILLIC SMALL LETTER A) and the third is setVal\U0001d69ee aka setVal\xf0\x9d\x9a\x9ee (with MATHEMATICAL MONOSPACE SMALL U).
See also:
Does the Go language have function/method overloading? (stackoverflow.com)
Why does Go not support overloading of methods and operators? (golang.org)
Alternative for function overloading in Go? (stackoverflow.com)

Convert function to another type (function casting) in Go

I've recently learnt that in the net/http package, there's a pattern of usage that keeps confusing me most. It is function type conversion. It is like this:
(function a) ->convert to-> (type t)
(type t) ->implentments-> (interface i)
So, if there's a function that takes interface i as its parameter, it will invoke the function a, this is the way net/http implements it.
But when I write my own code, I've had many misunderstandings on this pattern. My code goes like this:
package main
import (
"fmt"
)
type eat interface {
eat()
}
type aaa func()
func (op *aaa) eat() {//pointer receiver not right
fmt.Println("dog eat feels good")
}
///////////////////////////////////////////////
func dog() {
fmt.Println("I'm a dog")
}
///////////////////////////////////////////////
func feelsGood(a eat) {
a.eat()
}
func main() {
b := aaa(dog)
feelsGood(b)
}
//error:aaa does not implement eat (eat method has pointer receiver)
Type aaa has method eat, the same function name and parameter signature, which conforms to the rule of interface eat, but why does it give that error? Does the receiver matter?
Another question is with only a function and type, excluding an interface, the code goes like this:
package main
import (
"fmt"
)
type aaa func()
func (op *aaa) eat() {
op()
}
///////////////////////////////////////////////
func dog() {
fmt.Println("I'm a dog")
}
///////////////////////////////////////////////
func main() {
obj:=aaa(dog)
obj.eat()
}
//error:cannot call non-function op (type *aaa)
First, is op an anonymous function, regardless of the error?
Second, it works well after I remove the asterisk, but why? op is instance of type aaa, receiver is op, does op stand for function dog()? The http package uses f(w,r) the same way, but it is a little bit of hard to understand. Is op a type, or an instance, or an anonymous function?
It seems like my comprehension of function converting is not right, but I've also checked many posts on Google, and none of them can teach me how to think of it and use it correctly.Thank you!
Question 1:
In Go, for a type T (like aaa in your case), T and *T have different method sets.
So, a value of type T can only access method:
func(t T)Foo() { ... }
While a value of type *T can access both methods:
func(t T)Foo() { ... }
func(t *T)Bar() { ... }
In your case, you have two options. Either you declare the eat method for aaa instead od *aaa:
func (op aaa) eat() {
op()
}
Or you pass the pointer to b to feelsGood:
feelsGood(&b)
Question 2:
Yes, this question is related to the first. But in this case you can access the method because obj.eat() will be short for (&obj).eat().
Your problem here is that you cannot call a function on the function pointer (op *aaa). Your options are to either create the method for aaa instead of *aaa:
func (op aaa) eat() {
op()
}
Or to call the op function on the value and not the pointer:
func (op *aaa) eat() {
(*op)()
}
For the first part of your question: See http://golang.org/doc/faq#different_method_sets which exmplains everything better than I could. You may even search stackoverflow and the golang-nuts mailing list for this question as this comes up very often.
The second is just the same IMHO: aaa doesn't have an eat-method (only *aaa has).

Converting composed objects to json in Go

I am new to Go and am unsure about how to approach this problem. In OOP terms, I have a base class of Animal and two subclasses of Cat and Dog. I want to specify a ToJson method for Animal which will work for all animals.
My problem is that when I call dog.ToJson() I only get the Dog properties of dog and none of the Animal properties.
How can I make ToJson work as expected (ie with recursion)?
edit: Changed code to reflect suggestions in answer by lbonn, which I could not get to work how I want it to.
edit2: consistency in question following code change
package main
import (
"encoding/json"
"fmt"
)
type Animal struct {
Name string
}
type Cat struct {
CatProperty int64
Animal
}
type Dog struct {
DogProperty int64
Animal
}
func ToJson(i interface{}) []byte {
data,err := json.Marshal(i)
if err != nil {
panic("???")
}
return data
}
func main() {
dog := Dog{}
dog.Name = "rex"
dog.DogProperty = 2
fmt.Println(string(ToJson(dog)))
// Prints {"DogProperty":2}
// I want it to print {"Name":"rex","DogProperty":2}
}
Json encoding of anonymous fields was dropped from go 1. Hopefully it will be back in go 1.1. See https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/jYMHbEv44r4 for more details.
So the best you can get with the standard library right now (with go 1) is http://play.golang.org/p/LncNFeN8ys
You can always use skelterjohn's patch https://github.com/skelterjohn/json/ to support anonymous fields till go 1.1 is released.
Or use tip, installing from source that has this issue fixed. see https://codereview.appspot.com/6460044
Here, the ToJson method applies to the anonymous field Animal of Dog. The call d.ToJson is only a visibility shortcut to d.Animal.ToJson.
GoLang Tutorials: Anonymous fields in struct
Here, I would write a function instead of a method (a simple wrapper around Marshal):
func ToJson(i interface{}) []byte {
data,err := json.Marshal(i)
if err != nil {
panic("???")
}
return data
}
This is not specific to animals or dogs but it doesn't really need to.
More generally, there is no real notion of inheritance in go. The object paradigm used in the language is quite different from mainstream OOP, like in Java or C++. The Go FAQ provides some good clarifications about it.

Working with function types in Go

I wanted to create a function of a certain type. I've found one way to do it, but there must be other, cleaner and nicer ways that do not include using var. What are the alternative ways to declare the function english of type Greeting?
package main
import "fmt"
type Greeting func(name string) string
func (g Greeting) exclamation(name string) string {
return g(name) + "!"
}
var english = Greeting(func(name string) string {
return "Hello, " + name
})
func main() {
fmt.Println(english("ANisus"))
fmt.Println(english.exclamation("ANisus"))
}
In the example above, I can't exchange var english = Greeting... with english := Greeting..., nor can I remove the Greeting(func ...) and just have the func stand alone since then I won't be able to access the exclamation method.
If mentioning var is your main problem, you can drop it easily, by changing = into :=, like this:
english := Greeting(func(name string) string {
return ("Hello, " + name);
})
But you don't even have to cast your function into Greeting. The spec says this about function types:
A function type denotes the set of all functions with the same parameter and result types.
And this about type identity:
Two function types are identical if they have the same number of parameters and result values, corresponding parameter and result types are identical, and either both functions are variadic or neither is. Parameter and result names are not required to match.
This means that each function has its own function type. If two functions have the same signature (parameter and result types), they share one function type. By writing type Greeting func... you're just giving a name to a particular function type, not defining a new one.
So the following code works, and I hope shows the right way to work with function types in Go:
package main
import "fmt"
type Greeting func(name string) string
func say(g Greeting, n string) { fmt.Println(g(n)) }
func french(name string) string { return "Bonjour, " + name }
func main() {
english := func(name string) string { return "Hello, " + name }
say(english, "ANisus")
say(french, "ANisus")
}
Notice that I also dropped semicolon and parenthesis from your english function. Go developers don't use these punctuations if they don't have to.
UPDATE: Now that you've provided a sample code I can clearly understand the problem.
For this purpose your code is good enough and there are not much other ways of doing it. If you like you can cast just before calling the method:
english := func(name string) string { return "Hello, " + name }
Greeting(english).exclamation("ANisus")
But I'm not sure this is an improvement. I'm just saying that for what you want to do there does not seem to be other ways to write the code.
That is, if we don't want to change your types. I mean, the whole idea of calling a method on a function type seems a little weird. Not that it's wrong, but a little rare. Another way of achieving the same effect in a more usual way is through a struct type and having a field for the function. Something like this:
package main
import "fmt"
type Greeting struct {
say func(name string) string
}
func newGreeting(f func(string) string) *Greeting {
return &Greeting{say: f}
}
func (g *Greeting) exclamation(name string) string { return g.say(name) + "!" }
func main() {
english := &Greeting{say: func(name string) string {
return "Hello, " + name
}}
french := newGreeting(func(name string) string {
return "Bonjour, " + name
})
fmt.Println(english.exclamation("ANisus"))
fmt.Println(french.exclamation("ANisus"))
}
Here english and french show two different ways of coding the same thing. Again, I'm not saying that this is the better solution, but a more usual and more flexible way of achieving the same effect.
Trying to separate issues here,
type Greeting func(string) string
func english(name string) string {
return return "Hello, " + name
}
func main() {
var g Greeting
g = english
fmt.Println(g("ANisus"))
}
Is the way to declare the function english of type Greeting. Notice Greeting is not used in the definition of english, so this may not meet your requirement of declaring a function of a specific type. Otherwise, sorry, there is no way in Go to define a function of a specific (that is, separately defined) type. It might be nice to type something like,
english := Greeting {
return return "Hello, " + name
}
but no, there is no way in Go. The declaration of english can't use Greeting, and must repeat the function signature. Instead the requirement that english is of type Greeting is made only in the assignment
g = english
g is declared of type Greeting. If english isn't the same type, the line won't compile.
Beyond the issue of repeating the type signature--the issues of methods, for example--it's not clear if you're still looking for other ways to organize the functionality of your example. It can certainly be done other ways. A bigger example though, maybe posed as a separate question, would help.