Reason of third return statement in method - go

I’m new to Go and to practice I do some coding exercice on Exercism. I stubbled on a particular exercice in which I’m having a hard time undestanding the solution. Here’s the code:
// Ints defines a collection of int values
type Ints []int
// Lists defines a collection of arrays of ints
type Lists [][]int
// Strings defines a collection of strings
type Strings []string
// Keep filters a collection of ints to only contain the members where the provided function returns true.
func (i Ints) Keep(strainer func(int) bool) (o Ints) {
for _, v := range i {
if strainer(v) {
o = append(o, v)
}
}
return
}
// Discard filters a collection to only contain the members where the provided function returns false.
func (i Ints) Discard(strainer func(int) bool) Ints {
return i.Keep(func(n int) bool { return !strainer(n) })
}
My Problem comes with the Discard Method, I dont understand the second return statement in the curly braces since the Keep function is suppose to return a value of type Ints and not a boolean statement unless I missed something, if someone could break down the Discard function for me it would be helpful.
Thanks

The Keep method takes a function as a parameter. It expects it to be func (int) bool - a function taking an int and returning a bool.
When Keep is invoked in Discard, the code passes it an anonymous function with the right signature (take int, return bool). This anonymous function invokes strainer (which is a function passed into Discard) and returns its response, negated.
The idea is that strainer is a filter function: it tells you which elements to keep. So the implementation of Keep is straightforward: iterate over all elements, and keep only those for which strainer returns true.
Discard is written in a clever way using Keep, instead of also writing a loop like this:
func (i Ints) Discard(strainer func(int) bool) (o Ints) {
for _, v := range i {
if !strainer(v) {
o = append(o, v)
}
}
return
}
It instead invokes Keep with a function that inverts the result of strainer.

Related

GoLang Implement an anonymous function of a custom type

I have completed the strains exercise on exercism.io. I am refactoring my solution. For context: Ints.Keep takes in a predicate function and returns a filtered slice of type Ints for every element where the predicate function is true. Conversely Discard returns all elements for which the predicate is not true. Discard returns the inverse of Keep. I implemented it like so:
func (i Ints) Keep(pred func(int) bool) (out Ints) {
for _, elt := range i {
if pred(elt) {
out = append(out, elt)
}
}
return
}
func (i Ints) Discard(f func(int) bool) Ints {
return i.Keep(func(n int) bool { return !f(n) })
}
Example usage
Now I am trying to clean it up slightly. I want to create:
type Predicate func(int) bool
Then I want to implement Keep and Discard where the input is a Predicate. I run into the issue when I try to create an anonymous function within Discard to return Keep:
func (i Ints) Discard(p Predicate) Ints {
return i.Keep(Predicate(n int) { return !p(n) })
}
Is this possible? I can't find a way to create an anonymous function of a named func type.
You can do it by casting the anonymous function as a Predicate Like this:
func (i Ints) Discard(p Predicate) Ints {
return i.Keep(Predicate(func(i int) bool { return !p(i) }))
}
This isn't quite as clean as I wanted, but I bet this is the best.
I guess you are misunderstanding text replacement with type subtitution, see:
f func(int) bool gets replaced by p Predicate
func and bool (wrapping (n int)) somehow gets replaced by Predicate.
As far i remember type substitution is very straightforward and that is not the case here... "Mu is too short" highlights a good example if you insist on using type... although it is perfect to use anonymous functions definitions and declarations.
Another way to write code that comes to my mind that you might find useful is:
type Predicate func(int) bool
func (i Ints) Discard(pred Predicate) Ints {
var anonymousComplementFunc Predicate = func(n int) bool {
return !pred(n)
}
return i.Keep(anonymousComplementFunc)
}

Return only the first result of a multiple return values in golang

Absolute newbie question here.
Some functions in Go return more than one value (normally, the value and an error). I was writing a func who return the return value of one of those functions, and even if it is very easy to put the values on variables and return only the first one, I have the doubt if I could do the same in only one line without the extra variable. This is something often uses in other languages like C, Java, C#, Ruby, etc
func someFunc (param string) int {
// do something with the string, not very important
return strconv.Atoi(param)
}
I know this works
func someFunc (param string) int {
// do something with the string, not very important
var result int
result, _ = strconv.Atoi(param)
return result
}
It is this possible in Go? It is considered a "good practice" (like in Java*)
Note: Before someone say that this technique is not a good practice in Java, clarify that is not important for the question, but some people (like the ones in the company I work) encourage that style.
Use a short variable declaration for the shortest code to accomplish this goal:
func SomeFunc(parm string) int {
result, _ := strconv.Atoi(param)
return result
}
There is no one line solution without introducing a helper function that accepts two arguments and returns the first. One of these helper functions would be needed for each combination of types where you want to ignore a value.
Your best possible one-liner is a helper function written as:
func first(n int, _ error) int {
return n
}
func SomeFunc(param string) int {
return first(strconv.Atoi(param))
}
Note that:
the argument types and positions must match exactly
the second argument to first has the blank identifier (_), making it clear that you wish to completely ignore it. [1]
If you absolutely don't want to declare a named function, you may use a function literal, but that looks real ugly:
func SomeFunc(param string) int {
return func(n int, _ error) int { return n }(strconv.Atoi(param))
}
In general, the helper function is worth it if you have a lot of repetition in your code. Otherwise just use a temp variable, which looks clean and idiomatic:
func SomeFunc(param string) int {
n, _ := strconv.Atoi(param)
return n
}
Playground: https://play.golang.org/p/X8EOh_JVDDG
Once generics will be added to the language in Go 1.18, you will be able to write a helper function that can be used with any return pair and preserve type safety on the first one:
func first[T, U any](val T, _ U) T {
return val
}
func SomeFunc(param string) int {
return first(strconv.Atoi(param))
}
Go2 Playground: https://go2goplay.golang.org/p/vLmTuwzrl5o
Footnotes:
[1] Keep in mind that in case of strings.Atoi the second return value is an error, and ignoring errors is bad practice. However there are cases where the success of the operation truly doesn't matter, then it's fine to use _ to ignore the argument.

How to resolve whether pass objects via interface{} have not initializated fields

I have problem with resolve whether object which was pass as interface to function hasn't initializated fields, like object which was defined as just someObject{} is a empty, because all fields, has value 0, or nil
Problem becomes more complicated if I pass diffrent objects, because each object have diffrent type field value so on this moment I don't find universal way to this.
Example
func main(){
oo := objectOne{}
ot := objectTwo{}
oth := objectThree{"blah" , "balbal" , "blaal"}
resolveIsNotIntialized(oo)
resolveIsNotIntialized(ot)
resolveIsNotIntialized(oth)
}
func resolveIsNotIntialized(v interface{}) bool{
// and below, how resolve that oo and ot is empty
if (v.SomeMethodWhichCanResolveThatAllFiledIsNotIntialized){
return true
}
return false
}
I want to avoid usage switch statement like below, and additional function for each object, ofcorse if is possible.
func unsmartMethod(v interface{}) bool{
switch v.(type){
case objectOne:
if v == (objectOne{}) {
return true
}
// and next object, and next....
}
return false
}
As Franck notes, this is likely a bad idea. Every value is always initialized in Go. Your actual question is whether the type equals its Zero value. Generally the Zero value should be designed such that it is valid. The better approach would generally be to create an interface along the lines of:
type ZeroChecker interface {
IsZero() bool
}
And then attach that to whatever types you want to check. (Or possibly better: create an IsValid() test instead rather than doing your logic backwards.)
That said, it is possible to check this with reflection, by comparing it to its Zero.
func resolveIsNotIntialized(v interface{}) bool {
t := reflect.TypeOf(v)
z := reflect.Zero(t).Interface()
return reflect.DeepEqual(v, z)
}
(You might be able to get away with return v == z here; I haven't thought through all the possible cases.)
I don’t think there is a good reason (in idiomatic Go) to do what you are trying to do. You need to design your structs so that default values (nil, empty string, 0, false, etc.) are valid and represent the initial state of your object. Look at the source of the standard library, there are lots of examples of that.
What you are suggesting is easily doable via Reflection but it will be slow and clunky.
You could narrow the type which your function takes as an argement a little, not take an interface{} but accept one that allows you to check for non-zero values, say type intercae{nonZero() bool} as in the example code below. This will not tell you explicitly that it hasn't been set to the zero value, but that it is not zero.
type nonZeroed interface {
nonZero() bool
}
type zero struct {
hasVals bool
}
func (z zero) nonZero() bool {
return z.hasVals
}
type nonZero struct {
val int
}
func (nz nonZero) nonZero() bool {
return nz.val != 0
}
type alsoZero float64
func (az alsoZero) nonZero() bool {
return az != 0.0
}
func main() {
z := zero{}
nz := nonZero{
val: 1,
}
var az alsoZero
fmt.Println("z has values:", initialized(z))
fmt.Println("nz has values:", initialized(nz))
fmt.Println("az has values:", initialized(az))
}
func initialized(a nonZeroed) bool {
return a.nonZero()
}
Obviously as the type get more complex additional verification would need to be made that it was "nonZero". This type of pattern could be used to check any sort condition.

Use one return value?

I want to call my function test and use one of the return values. How do I say give me the first or second value? I thought the below would give me "one" but [1] is incorrect usage causing a compile error
package main
import (
"fmt"
)
func test() (int, string) { return 1, "one"; }
func main() {
i,sz:=test()
fmt.Printf("%d=%s\n",i,sz)
fmt.Printf("%s", test()[1]) //error
}
As far as I know, you can't subscript function return values. You can do:
_, someString := test();
fmt.Println(someString);
Citing the Go Language Specification:
A primary expression of the form a[x]
denotes the element of the array, slice, string or map a indexed by x. The value x is called the index or map key, respectively. [...] Otherwise [if a is not an array, slice string or map] a[x] is illegal.
Multiple return values in Go, however, are not arrays being returned, but a separate language feature. This must be so, because an array can only hold elements of a single type, but return values can be of different types.
But since return values are not arrays (or slices, strings or maps), the a[x] syntax is, per language spec, a syntax error. As a result, as #dav has already correctly stated, you will have to actually assign the return value to a variable in order to use it elsewhere.
In special cases, you may be able to use this bit of trivia to avoid variable assignment:
As a special case, if the return values of a function or method g are equal in number and individually assignable to the parameters of another function or method f, then the call f(g(parameters_of_g)) will invoke f after binding the return values of g to the parameters of f in order.
Which makes the following possible:
func foo() (int, string) {
return 42, "test";
}
func bar(x int, s string) {
fmt.Println("Int: ", x);
fmt.Println("String: ", s);
}
func main() {
bar(foo())
}

How to access individual values from a multi-value returning function?

Go functions can return multiple values:
func f() (int, int) {
return 2, 3
}
Is there any way to access individual values from such a multi-value returning function except assignment, i.e. suppose there is
func g(i int) {...}
is there is simpler way to write the following two lines?
_, i = f()
g(i)
My personal favorite would be g(f()[1]) but that's not possible either.
The current solution used by the standard library is to write simple helper functions which are dropping the unwanted return values. For example, take a look at the template package.
A lot of functions there return a (*Template, os.Error) tuple, but there is a helper called template.Must() which only returns a *Template and panics if the error isn't nil.
Alternatively, a general helper function like func extract(index int, values ...interface{}) interface{} might do the trick. But since there isn't support for generics yet, I wouldn't write something like that.
Use an anonymous struct instead of multiple return values.
func f() (struct{i,j int}) {
return struct{i, j int}{2, 3}
}
func g(i int) { ... }
func main() {
g(f().j)
}
Of course this only works when you are writing the function. Though you can wrap existing ones with this if you want.
g(func(fst,snd int) int { return snd }(f()))
or defined snd
func snd(x, y int) int {
return y
}
g(snd(f()))
or if function return array
func f() ([2]int) {
return [2]int{2, 3}
}
g(f()[1])
There isn't a simpler way.
A possible solution would look for example like this:
g(f().1)
There is no syntactic support for a feature like this one in Go.

Resources