Finding functions that return a specific type - go

Perhaps this is a silly question, but is there a way to find all functions (in the standard library or GOPATH) that return a specific type?
For example there are many functions that take io.Writer as an argument. Now I want to know how to create an io.Writer and there are many ways to do so. But how can I find all the ways easily without guessing at packages and looking through all the methods to find those that return an io.Writer (or whatever other type I'm after)?
Edit: I should extend my question to also find types that implement a specific interface. Sticking with the io.Writer example (which admittedly was a bad example for the original question) it would be good to have a way to find any types that implement the Writer interface, since those types would be valid arguments for a function that takes takes an io.Writer and thus answer the original question when the type is an interface.

Maybe not the best way but take a look at the search field at the top of the official golang.org website. If you search for "Writer":
http://golang.org/search?q=Writer
You get many results, grouped by categories like
Types
Package-level declarations
Local declarations and uses
and Textual occurrences
Also note that io.Writer is an interface, and we all know how Go handles interfaces: when implementing an interface, there is no declaration of intent, a type implicitly implements an interface if the methods defined by the interface are declared. This means that you won't be able to find many examples where an io.Writer is created and returned because a type might be named entirely different and still be an io.Writer.
Things get a little easier if you look for a non-interface type for example bytes.Buffer.
Also in the documentation of the declaring package of the type the Index section groups functions and methods of the package by type so you will find functions and methods of the same package that return the type you're looking for right under its entry/link in the Index section.
Also note that you can check the dependencies of packages at godoc.org. For example you can see what packages import the io package which may be a good starting point to look for further examples (this would be exhausting in case of package io because it is so general that at the moment 23410 packages import it).

In my days coding I'm personally rare in need to find functions returning Int16 and error(func can return few values in Go, you know)
For second part of your question there exists wonderful cmd implements written by Dominik Honnef go get honnef.co/go/implements
After discover type that satisfy your conditions you can assume constructor for type (something like func NewTheType() TheType) would be just after TheType declaration in source code and docs. It's a proven Go practice.

Related

In go language, may I define allowed values of a string in a struct and/or force creation only via constructor? Or avoid direct creation of a struct? [duplicate]

This question already has answers here:
Creating a Constant Type and Restricting the Type's Values
(2 answers)
What is an idiomatic way of representing enums in Go?
(14 answers)
Closed 8 months ago.
I have a struct Direction with a value of type string. Direction should be N, S, W or E.
type Direction struct {
value string
}
Inspired by an answer of this question: Does Go have "if x in" construct similar to Python? I guess a good way to create Direction in a valid manner can be this one:
func NewDirection(direction string) Direction {
switch direction {
case "N","S","W","E": return Direction{direction}
}
panic("invalid direction")
}
But this is not enough for me because I can still create invalid Direction:
d := Direction{"X"}
I also found this interesting article about enforcing the use of constructor in go. Reading this article I can see that is necessary the usage of another package. May I have a "protected" struct in, for example, main package?
You've already done almost everything you should do by convention:
make the field unexported
provide a constructor
put a comment on the type stating that the constructor should be used, and explain how zero-values are treated (if that matters)
Now users of the package can't modify the field, and the existence of the constrictor makes it clear that it should be called to create valid instances. This is the convention that is set by the standard library.
Sure, there are other ways that you can make it even harder to invalidate values but this is essentially just wasting time and overcomplicating your code for the sake of an unwinnable arms race against an imaginary opponent.
If someone doesn't understand the language and doesn't read documentation, then they're always going to find a way to misuse it. If they are actively trying to sabotage themselves, there's nothing you can do to stop them and no reason to either.
Packages are the smallest functional unit of code organization in Go. There is no way to protect field at, for example, the file level. Even files within the same package effectively operate as if all their code was in the same file. Therefore, any code in the same package as the constructor will have the same privileges as the constructor.

Receiver naming consistency

The official documentation recommands to use the same receiver name everywhere. But does it really make sense to comply with that?
I mean, I imagine something like func (first Foo) concat(second Foo) (combinded Foo) to be more expressive, while first does only make sense in that very context of concatenation. If we don't go that route, we're basically forced to resort to some agnostic but useless receiver naming like f, wasting an opportuniy for self-documenting code.
Given that 1. You have a good method name, 2. The receiver type is readily apparent from the method declaration, most of the time a short name like f is quite alright. In the case where you need to differentiate the receiver from a parameter, it suggests that you could use a regular function rather than a method, since apparently the receiver doesn't have an obvious meaning that follows from the method name.
Go Wiki: Receiver Names:
The name of a method's receiver should be a reflection of its identity; often a one or two letter abbreviation of its type suffices (such as "c" or "cl" for "Client"). Don't use generic names such as "me", "this" or "self", identifiers typical of object-oriented languages that gives the method a special meaning. In Go, the receiver of a method is just another parameter and therefore, should be named accordingly. The name need not be as descriptive as that of a method argument, as its role is obvious and serves no documentary purpose. It can be very short as it will appear on almost every line of every method of the type; familiarity admits brevity. Be consistent, too: if you call the receiver "c" in one method, don't call it "cl" in another.
If you have a single method, it probably doesn't matter. If you have a type with many (maybe even dozens of methods), it does help if you use the same receiver name in all. It's much easier to read and understand.
Also if you want / have to copy some code from one method to another (refactoring), if the receiver name is the same, you can just do copy / paste and your done, you don't have to start editing the different names.
Also Dave Cheney: Practical Go: Real world advice for writing maintainable Go programs:
2.4. Use a consistent naming style
Another property of a good name is it should be predictable. The reader should be able to understand the use of a name when they encounter it for the first time. When they encounter a common name, they should be able to assume it has not changed meanings since the last time they saw it.
For example, if your code passes around a database handle, make sure each time the parameter appears, it has the same name. Rather than a combination of d *sql.DB, dbase *sql.DB, DB *sql.DB, and database *sql.DB, instead consolidate on something like;
db *sql.DB
Doing so promotes familiarity; if you see a db, you know it’s a *sql.DB and that it has either been declared locally or provided for you by the caller.
Similar advice applies to method receivers; use the same receiver name every method on that type. This makes it easier for the reader to internalise the use of the receiver across the methods in this type.
Also an interesting reading: Neither self nor this: Receivers in Go

Create constants visible across packages, accessible directly

I would like to define my Error Codes in a package models.
error.go
package models
const{
EOK = iota
EFAILED
}
How can I use them in another package without referring to them as models.EOK. I would like to use directly as EOK, since these codes would be common across all packages.
Is it the right way to do it? Any better alternatives?
To answer you core question
You can use the dot import syntax to import the exported symbols from another package directly into your package's namespace (godoc):
import . "models"
This way you could directly refer to the EOK constant without prefixing it with models.
However I'd strongly advice against doing so, as it generates rather unreadable code. see below
General/style advice
Don't use unprefixed export path like models. This is considered bad style as it will easily globber. Even for small projects, that are used only internally, use something like myname/models. see goblog
Regarding your question about error generation, there are functions for generating error values, e.g. errors.New (godoc) and fmt.Errorf (godoc).
For a general introduction on go and error handling see goblog
W.r.t. the initial question, use a compact package name, for example err.
Choosing an approach to propagating errors, and generating error messages depends on the scale and complexity of the application. The error style you show, using an int, and then a function to decode it, is quite C-ish.
That style was partly caused by:
the lack of multiple value returns (unlike Go),
the need to use a simple type (to be easily propagated), and
that gets translated to text with a function (unlike Go's error interface), so that the local language strings can be changed.
For small apps with simple errors strings. I put the packages' error strings at the head of a package file, and just return them, maybe using errors.New(...), or fmt.Errorf if the string needs to be completed using some data.
That 'int' style of error reporting doesn't offer something as flexible as Go's error interface. The error interface lets us build information-rich error structures, to return useful information, and not just an int value or string.
An implication is different packages can yield different real-types which implement the Error interface. We don't need to agree a single error real-type across an entire set of packages. So error is an interface which can be easily propagated, like an int, yet, the real-type of error can be much richer than an int. Error generation (implementing Error) can be as centralised or distributed as we need, unlike strerror()-style functions which can be awkward to extend.

Document duck types with multiple methods in YARD

YARD allows me to specify types for method parameters and return values. As I really like to duck type it is nice to see that YARD also supports defining types by specifying methods they must support.
As you can see here, expressions like #first_method, #second_method are interpreted as a logical disjunctions. This means an object needs to support #first_method or #second_method or both. This is not what I need.
I would like to be able to specify that an object is required to support both #first_method and #second_method for my parameter. Is there a way to specify this?
There is no idiomatic syntax for specifying a compound duck-type interface. That said, note that all type specifications are really just free-form text; the YARD types parser link given in the question is simply a set of conventional or idiomatic syntaxes for specifying common interfaces. If you think of a smart way to specify these types (and it makes sense to your users), you are free to do so. Perhaps something like #first#second might work, or #first&#second.
My recommendation, however, would be to create a concrete type to wrap this ad-hoc interface. Even if you don't actually use the type in your runtime, it would serve as object in your domain to explain the interface to your users. For example, by creating a class Foo with the two methods #first and #second, and then documenting those two methods, you could now use Foo as your type. You could explain in the Foo class documentation that it is never actually used in code and just exists as an "interface", if that's the case. You could also make Foo a "module" to denote that it is more of an "interface" (or "protocol", if you prefer that language) than a concrete type.

Getting a reflect.Type from a name

If I have a name of a type (i.e "container/vector"), is there a way to lookup the reflect.Type that has the given name? I'm trying to write a simple database-backed workqueue system and this it would be very difficult without this feature.
I can't see how this would be possible in any trivial way (or at all), since name resolution is part of the compiler/linker, not the runtime.
However, http://github.com/nsf/gocode might offer up some ideas. Though I'm pretty sure that works by processing the .a files in $GOROOT, so I still don't see how you'd get the reflect.Type. Maybe if the exp/eval package was more mature?
Of course if you know all the possible types you'll encounter, you could always make a map of the reflect.Type. But I'm assuming you're working with unpredictable input, or you would've thought of that.
Only way to create a reflect.Type is by having a concrete value of the intended type first. You can't even create composite-types, such as a slice ([]T), from a base type (T).
The only way to go from a string to a reflect.Type is by entering the mapping yourself.
mapping := map[string]reflect.Type {
"string": reflect.Typeof(""),
"container/vector": reflect.Typeof(new(vector.Vector)),
/* ... */
}

Resources